← IB Computer Science

A1.4 · Book pp. 103–110

Translation

Your level

A CPU only understands machine code. This short section compares four ways of getting there from the code you write.

What you need to know

There is one syllabus point, A1.4.1: evaluate the translation processes of interpreters and compilers. It is for both SL and HL. “Evaluate” means weighing strengths and weaknesses for a situation, so a list of facts will not earn full marks.

💡 An analogy

An interpreter is like a friend translating a book aloud, sentence by sentence, every time you read it. A compiler is like a translator who converts the whole book once. You wait at the start, but then you can read it quickly as often as you like.

Next: how they work →

Interpreters

An interpreter takes one statement at a time, translates it and runs it at once. No separate machine-code program is saved. You get immediate feedback, but the work is repeated each run. Ruby, JavaScript and Python are usually run this way.

Compilers

A compiler translates the whole program before it runs, through lexical analysis, syntax analysis, semantic analysis, optimization and code generation. The result needs no further translation and runs fast. C and C++ are the usual examples.

🔬 Lab: when is the error found?

This toy language has let x = 5, print "text" and print x / 2.

Choose a translator.

Try the syntax preset with both. The interpreter prints the first lines before it stops, and the compiler prints nothing but lists every error.

✍️ Try it in real languages

  1. Run this Python. Which lines print before it stops?
    def greet(name):
        print("Hello, " + name + "!")
    
    greet("Mali")
    print("Letters:", len(name))   # name only exists inside greet()
  2. Compile this Java. Does any line run?
    public class Greeting {
        public static void main(String[] args) {
            System.out.println("Hello");
            System.out.println("No semicolon here")
        }
    }
  3. At what point was each error found, and how would that affect your day as a developer?
Model answers
  1. “Hello, Mali!” prints, then a NameError stops the program.
  2. No. The compiler rejects the file, so nothing runs.
  3. Python found it at runtime, after some work was done. Java found it at compile time, so it never reached a user, but it needs a compile step every time.

Next: bytecode and JIT →

Bytecode interpreters

Source code is first compiled to compact, platform-independent bytecode. A virtual machine then runs it. Java compiles to .class files for the JVM, and Python caches bytecode in .pyc files. The same bytecode runs anywhere with a suitable virtual machine.

Source code Compiler Bytecode JVM on Windows JVM on macOS JVM on Linux
Original diagram: one bytecode file, one virtual machine per platform.

Just-in-time (JIT) compilation

A JIT compiler starts by interpreting bytecode. It watches for hot spots, compiles those to machine code during the run and caches the result. The JVM, the .NET runtime and browser JavaScript engines all do this.

🔬 Lab: when does compiling pay off?

Interpreted (10 units each run)
JIT (200 units once, then 1 each run)

The costs are made-up units. The idea holds in real systems: rarely run code is not worth compiling, which is why JIT compilers only choose hot spots.

Next: evaluate →

A1.4.1 Evaluating the four approaches

CriterionCompilerInterpreterBytecodeJIT
Error detectionSyntax and some semantic errors found before running. Runtime errors can still happenFound as each line runs, so an unreached error stays hiddenSome found at bytecode stage, others at runtimeAs for bytecode, with runtime errors still possible
Translation timeHigh up frontAlmost none up front, but repeated on every runModerateLow at start, with short compile pauses while running
Execution speedFastestSlowestModerateStarts moderate, gets faster
PortabilityLow: compile again for each platformHigh, wherever an interpreter existsHigh, wherever a VM existsHigh, and tuned to the hardware at runtime
Best forSystem software, games, real-time workScripting, prototypes, learningCross-platform appsLong-running servers and browsers

Matching method to situation

SituationBest methodWhy
A startup testing a Python web prototypeInterpreterChanges can be run at once, with no compile step
A low-latency trading system in C++CompilerOptimized machine code gives the highest speed
A Java business app on Windows, macOS and LinuxBytecode with JITOne bytecode file runs on each JVM, and JIT recovers the speed

✏️ Book correction

The book’s summary table says compilers catch “all errors” before execution. Its own text is right: they catch syntax errors and some semantic errors. Logic errors and runtime errors such as bad input can still get through.

The book also says JIT can “catch” issues and improve reliability. JIT is about speed. It does not make a program more correct.

⚠️ Common mistakes

  • Languages are not “compiled” or “interpreted” by nature. These are ways of running them, and Python itself uses bytecode.
  • Portability is about the translator being available. Compiled machine code targets one kind of machine.

Next: review →

Quick quiz

1. What does a compiler produce?
2. Why does an interpreted program usually run more slowly?
3. A Python script has a bug inside an `if` that never runs. What happens?
4. Which is an advantage of a compiled program?
5. What runs Java bytecode?
6. What is a “hot spot” in JIT compilation?
7. Which suits a long-running web server best?
8. Can a compiled program still crash at runtime?

Exam-style questions

These are written for this site in the style of Paper 1. Answer on paper first, then open the mark points.

  1. Compare a compiler and an interpreter for software development. [4]

    Mark points
    • A compiler translates everything before running, while an interpreter translates as it runs [1].
    • Compiled programs run faster, because translation is not repeated [1].
    • Interpreters give immediate feedback, which suits testing [1].
    • Compiled programs must be rebuilt for each platform, while source code can run on any platform with an interpreter [1].
  2. Describe just-in-time compilation and explain how it combines interpretation and compilation. [4]

    Mark points
    • Source code is first converted to bytecode [1].
    • The bytecode is interpreted on a virtual machine [1].
    • Frequently executed sections are detected and compiled to machine code during the run [1].
    • That machine code is cached and reused, which gives near-compiled speed with the portability of bytecode [1].
  3. Compare the error detection of compilers and interpreters and discuss the effect on development. [4]

    Mark points
    • Compilers report syntax and some semantic errors before anything runs [1].
    • Interpreters find errors when the line is reached [1].
    • Compilation can prevent many errors from reaching users, but each change needs a rebuild [1].
    • Interpreted development is quicker to test, but errors on unreached paths may appear later [1].
  4. A company needs one desktop application for Windows, macOS and Linux. Justify using bytecode. [3]

    Mark points
    • Bytecode is platform-independent [1].
    • The same file runs on any machine with the virtual machine [1].
    • So the company avoids compiling and testing a separate build for each platform [1].