High-Level vs Low-Level Languages
All programs written by programmers must be translated into machine code (binary 1s and 0s) before the CPU can execute them. The tool that does this translation is called a translator.
High-Level Language (HLL)
Written to be easy for humans to read and write. Uses English-like keywords and abstracts away hardware details.
Examples: Python, Java, C#, Visual Basic
One line of HLL code may produce many lines of machine code.
Must be compiled or interpreted before the CPU can run it.
Low-Level Language (LLL)
Closer to machine code. Operates directly on the hardware. Hard for humans to write.
Examples: Assembly language, Machine code
Assembly uses mnemonics (MOV, ADD, JMP) — one instruction = one machine code instruction.
Must be assembled using an assembler.
Compilers
A compiler translates the entire source program into machine code (an executable file) all at once, before the program runs. The resulting executable can be run directly without needing the compiler again.
Source code
(.py, .java…)
→
Compiler
→
Object/Executable
(.exe, .class…)
→
CPU runs it
directly
⚙ Compiler: Advantages & Disadvantages
Resulting executable runs quickly — machine code is pre-generated
Source code is hidden in the executable — protects intellectual property
Executable runs without the compiler present
Errors reported after full compilation — all in one error report
Compilation takes time before the program can run
Hard to debug — errors listed by line number but you cannot step through
Compiled for a specific OS/hardware — not automatically portable
Full recompilation needed after every change to source code
Interpreters
An interpreter translates and executes the source code line by line at runtime. No executable file is created. The interpreter must be present every time the program runs.
Source code
(.py, .js…)
→
Interpreter
line by line
→
CPU executes
each line
⚡ Interpreter: Advantages & Disadvantages
Easier to debug — stops at the exact line where an error occurs
Faster development cycle — change code and run immediately, no compilation step
More portable — interpreter on any platform can run the same source code
Runs slower than compiled code — translation happens at runtime every time
Source code must be present (and visible) when distributing
Interpreter must be installed on every machine that runs the program
Stops at first error — later errors not detected until earlier ones fixed
Comparison Table
| Feature | Compiler | Interpreter |
| Translation method | Whole program at once | Line by line at runtime |
| Output | Executable file (.exe) | No output file produced |
| Execution speed | Fast | Slower |
| Debugging | Harder (line numbers only) | Easier (stops at error line) |
| Error reporting | All errors after full compilation | Stops at first error |
| Source code needed at runtime? | No (executable is standalone) | Yes |
| Translator needed at runtime? | No | Yes (interpreter must be installed) |
| Portability | Less portable (OS/hardware specific) | More portable (reuse same source) |
| Examples | C, C++, Java (javac) | Python, JavaScript (browser), Ruby |
Exam tip: A common 4-mark question asks to compare a compiler and an interpreter. The key differences are: (1) whole vs line-by-line translation, (2) produces an executable vs no file, (3) fast execution vs slower, (4) harder vs easier debugging. Learn these four pairs.
⚠️ Common Mistakes
- Saying "an interpreter is faster" — it is NOT. Compiled code runs faster. Interpreter is faster to develop with (no compilation step) but slower to run.
- Saying an interpreter "converts to machine code permanently" — it does not. Translation happens each time the program runs.
- Python is typically interpreted. Java is compiled to bytecode then interpreted by the JVM — but for GCSE just say Java uses a compiler (javac).