What a program is
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 0set count to 3while count is greater than 0: add count to total subtract 1 from countshow totalMost 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
total = 0count = 3while count > 0: total = total + count count = count - 1print(total)JavaScript
let total = 0;let count = 3;while (count > 0) { total = total + count; count = count - 1;}console.log(total);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
#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 * 414>>> total = 10>>> total * 220Most 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.
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 1set n to 4while n is greater than 1: multiply result by n subtract 1 from nshow resultShow 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.
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.
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 0set n to 2while n is at most 8: add n to total add 2 to nshow totalThere 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
total = 0n = 2while n <= 8: total = total + n n = n + 2print(total)JavaScript
let total = 0;let n = 2;while (n <= 8) { total = total + n; n = n + 2;}console.log(total);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
#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.