3.3.2 Interpreters and compilers
Why Translation Is Needed
CPUs execute only machine code (binary). High-level language source code must be translated into machine code before it can run. Two types of translator do this in fundamentally different ways: compilers and interpreters.
Compiler vs Interpreter
A compiler translates the entire source code into machine code in one pass before execution begins. The output is a standalone executable file that can be run directly by the CPU without the compiler being present.
- Process: source code → [compiler runs once] → machine code executable → execute repeatedly without retranslation
- Error reporting: all syntax and many type errors are reported at compile time before execution; the program will not run at all if there are errors
- Execution speed: fast — the executable is already machine code; no translation at run time
- Distribution: the compiled executable is distributed (not the source code), so intellectual property is protected
- Platform dependency: the compiled output is specific to one OS and architecture; separate compilations are needed for different platforms
- Examples of compiled languages: C, C++, Go, Rust
An interpreter translates and executes source code line by line at run time. The original source code (or a bytecode intermediate form) must be present every time the program runs; the interpreter is also required.
- Process: source code → [interpreter present at run time] → translate and execute one line at a time
- Error reporting: errors are found when the interpreter reaches the offending line during execution — the program runs until it hits an error
- Execution speed: slower — translation overhead occurs every time the program runs
- Portability: the same source code runs on any platform that has the correct interpreter installed
- Development benefit: easier to test and debug — the programmer can run code immediately without waiting for a full compile; partial programs can be tested
- Examples of interpreted languages: Python, JavaScript, PHP
Side-by-Side Comparison
| Property | Compiler | Interpreter |
|---|---|---|
| Translation timing | All at once before execution | Line by line during execution |
| Error detection | Before the program runs (compile time) | When the line with the error is reached (run time) |
| Execution speed | Faster (already machine code) | Slower (translation overhead each run) |
| Portability | Executable is platform-specific | Source code portable — needs correct interpreter |
| Source code needed at run time? | No — executable is self-contained | Yes — interpreter needs the source |
| Debugging ease | All errors reported at once; harder to locate | Errors found at point of execution; easier to pinpoint |
Key Takeaways
- Compiler: translates all at once before execution → faster executable; errors at compile time; platform-specific output.
- Interpreter: translates line by line at run time → slower; errors at the offending line; source code portable across platforms with an interpreter.
- Python uses an interpreter; C and C++ use compilers.
- Neither approach is universally better — the right choice depends on the priorities: speed vs portability, protection of source code vs ease of debugging.