What a program is

Beginner25 min

Explain source code, compiling and interpreting, and trace a small program by hand to predict what it does.

What you will learn
  • Explain what source code is and how it differs from machine code
  • Distinguish a compiler from an interpreter and say what a runtime does
  • Trace a short program by hand and predict its output
On this page

A computer does exactly what it is told, and nothing else. A program is the telling: a list of instructions precise enough that a machine with no common sense can follow it. This lesson explains what that list looks like, how it reaches the processor, and how to read one the way a computer does.

Instructions, in order

A program is a sequence of instructions. The computer runs them one at a time, from the top, unless an instruction says to jump somewhere else. Each instruction does something small: store a number, add two numbers, compare two values, print a character.

Here is a five-line program in pseudocode, which is plain, informal notation that is not tied to any language:

set total to 0
set count to 3
while count is greater than 0:
add count to total
subtract 1 from count
show total

Most of the line count comes from the loop. A loop repeats its indented lines until the condition stops being true. You will meet loops properly in the lessons on control flow; for now, read them as “do this again while the condition holds”.

Tracing by hand

The most useful skill in this lesson is to be the computer. A trace is a table that records every variable after every step.

Step Instruction count total
1 set total to 0 - 0
2 set count to 3 3 0
3 loop test: 3 greater than 0, so enter 3 0
4 add count to total 3 3
5 subtract 1 from count 2 3
6 loop test: 2 greater than 0 2 3
7 add count to total 2 5
8 subtract 1 from count 1 5
9 loop test: 1 greater than 0 1 5
10 add count to total 1 6
11 subtract 1 from count 0 6
12 loop test: 0 greater than 0 is false, so leave the loop 0 6
13 show total prints 6 0 6

The program adds 3 + 2 + 1. Here it is in four real languages. Every one of them prints 6.

Python

trace_program.py
total = 0
count = 3
while count > 0:
total = total + count
count = count - 1
print(total)

JavaScript

trace_program.js
let total = 0;
let count = 3;
while (count > 0) {
total = total + count;
count = count - 1;
}
console.log(total);

Java

TraceProgram.java
public class TraceProgram {
public static void main(String[] args) {
int total = 0;
int count = 3;
while (count > 0) {
total = total + count;
count = count - 1;
}
System.out.println(total);
}
}

C

trace_program.c
#include <stdio.h>
int main(void) {
int total = 0;
int count = 3;
while (count > 0) {
total = total + count;
count = count - 1;
}
printf("%d\n", total);
return 0;
}

The ideas are identical. What differs is punctuation, and how much ceremony the language wants before the first useful line. Java and C need a main function, and C also needs an #include; Python and JavaScript need neither.

Source code and machine code

What you type is source code: text in a programming language, written for people to read. A processor cannot run text. It runs machine code, a stream of numbers where each pattern means one tiny operation, and different processor families (x86-64, ARM) use different patterns.

So something has to translate. There are two main strategies.

Compiler Interpreter
When it translates Once, before the program runs While the program runs
What it produces A separate executable file of machine code Nothing permanent; it acts on your code directly
Errors in unused code Often caught before anything runs Often found only when that line is reached
To run it Run the produced file Run the interpreter on your source
Typical examples C, Rust, Go Classic Python, Ruby, shell scripts

In practice the line is blurry. Python compiles your source to a compact intermediate form called bytecode and then interprets that. Java compiles to bytecode, and a virtual machine then runs it, translating hot sections to machine code on the fly. JavaScript engines do something similar. When a language course says “compiled” or “interpreted”, read it as “mostly”.

The runtime

Whatever the strategy, a program rarely runs alone. The runtime is the supporting machinery present while it runs: memory management, the standard library, error reporting, the virtual machine if there is one. When you hear “the Python runtime” or “the JVM”, this is what is meant.

The REPL

Many interpreted languages offer a REPL: Read, Evaluate, Print, Loop. You type one expression, the interpreter evaluates it, prints the result, and waits for the next. It is the fastest way to test a small idea.

>>> 2 + 3 * 4
14
>>> total = 10
>>> total * 2
20

Most popular languages have one, started with a single command:

Language Start the REPL with Leave with
Python python3 exit()
JavaScript node .exit
Java jshell /exit
C none built in write a small file instead

C has no standard REPL because C code must be compiled before it can run. The expression 2 + 3 * 4 typed into python3, node or jshell gives 14 in each.

A REPL is for experiments. Anything you want to keep, repeat or share belongs in a file, which is what the next lesson is about.

Common pitfalls

  • Reading code as a description instead of a procedure. Code is not a summary of what you want. It is the exact steps, in exact order. If you cannot say what a line does to the variables, trace it.
  • Assuming the computer understands intent. If a program adds the wrong numbers, it adds the wrong numbers faithfully.
  • Thinking compiled means fast and interpreted means slow. Speed depends on the language, the implementation and the task. Do not decide on that alone.
  • Tracing from the end of your memory instead of the table. Write the table. Skipping it is how people mis-predict loops by one.
ExerciseTrace it by hand

Trace this pseudocode and write the value of result after the program finishes. Use a table with one row per step. There is no input, and the answer is a single whole number.

set result to 1
set n to 4
while n is greater than 1:
multiply result by n
subtract 1 from n
show result
Show solution
After n result
start 4 1
pass 1: multiply result by 4, subtract 1 3 4
pass 2: multiply by 3, subtract 1 2 12
pass 3: multiply by 2, subtract 1 1 24
test: 1 greater than 1 is false 1 24

The program shows 24, which is 4 factorial. The loop stops when n reaches 1 because multiplying by 1 would change nothing.

ExerciseCompile or interpret?

A teammate says: “My program has a typo on line 80, but it ran fine for ten minutes before crashing.” Which strategy, compiled or interpreted, fits that story better, and why?

Show solution

Interpreted. An interpreter translates and runs code as it goes, so a mistake on line 80 is only noticed when execution reaches line 80. A compiler typically translates the whole file first and would reject a typo up front. Some mistakes slip past compilers too (a wrong calculation is never a compile error), but a plain typo that survives for ten minutes points to an interpreter.

ExerciseWrite the trace in your language

Translate this pseudocode into a program in the language of your choice and run it. It adds the even numbers 2, 4, 6 and 8.

set total to 0
set n to 2
while n is at most 8:
add n to total
add 2 to n
show total

There is no input. Expected output: one line, 20.

Show solution

Trace first: n takes the values 2, 4, 6 and 8, and then 10 ends the loop, so total is 2 + 4 + 6 + 8 = 20.

Python

even_total.py
total = 0
n = 2
while n <= 8:
total = total + n
n = n + 2
print(total)

JavaScript

even_total.js
let total = 0;
let n = 2;
while (n <= 8) {
total = total + n;
n = n + 2;
}
console.log(total);

Java

EvenTotal.java
public class EvenTotal {
public static void main(String[] args) {
int total = 0;
int n = 2;
while (n <= 8) {
total = total + n;
n = n + 2;
}
System.out.println(total);
}
}

C

even_total.c
#include <stdio.h>
int main(void) {
int total = 0;
int n = 2;
while (n <= 8) {
total = total + n;
n = n + 2;
}
printf("%d\n", total);
return 0;
}

All four print 20.

Summary

  • A program is an ordered list of precise instructions, and you can predict it by tracing the variables step by step.
  • Source code is text for people; machine code is what the processor runs. Compilers translate ahead of time, interpreters translate while running, and many languages mix both.
  • The runtime is the machinery present while your program runs.

Next: Editors, terminals and running code, where you will run your first program yourself.