The translation problem
A processor runs machine code, numeric instructions specific to its design. People write in languages that are easier to read. Something must bridge the two, and there are two broad strategies.
A compiler reads a whole program and produces a separate translated version, usually machine code, that can be run later. An interpreter reads the program and carries out its instructions directly, usually one statement or small unit at a time, without producing a standalone translated copy.
A common analogy is a book. A compiler resembles a translator who translates the whole book and hands over a finished edition. An interpreter resembles a person who translates aloud, sentence by sentence, as someone listens. Like most analogies, this one is imperfect, but it captures the timing difference.
Early history
In the early 1950s, programmers mostly worked in machine code and assembly language. Some began building tools that collected prewritten routines and assembled them into a program. Work by Grace Hopper and colleagues on early systems of this kind is often cited as an early step toward what we now call a compiler, although the terminology of the time was not fixed, and several groups worked on automatic coding systems.
The FORTRAN project at IBM, delivered in the late 1950s, was a landmark partly because its compiler produced efficient code. Its designers knew that scientific users would reject a language if programs ran much more slowly than hand-written assembly. Showing that a high-level language could be competitive was important to getting later languages accepted.
Interpretation has its own early history. The Lisp language, developed around the late 1950s, included the idea of a program that evaluates expressions written in the language itself. Interpreters were also natural for interactive systems, where a user typed a command and expected an immediate answer. Early BASIC systems took this approach.
How compiling works, briefly
A compiler usually proceeds in stages. It reads the text and checks that it follows the grammar of the language, works out what each piece means, and then generates the target code. Many compilers also try to improve the result, for instance by removing unnecessary steps.
The compiled output is run separately. Because the translation work is done in advance, the program can start quickly and the computer does not need the compiler present when the program runs. If the compiler also reports mistakes before the program ever runs, the programmer finds some problems early.
How interpreting works, briefly
An interpreter reads source code and performs the actions directly. The translation work happens while the program runs, so every run repeats some of it. In exchange, there is no separate build step. A programmer can change a line and try again right away, or type a single statement and see what happens, which suits learning and experimenting.
Interpreters also make it easier to run the same program on different kinds of computers: only the interpreter needs to be adapted to each machine, not the program itself. This was one reason scripting languages used the approach, and it is also why many beginners meet programming this way.
Trade-offs
Neither approach is simply better. General tendencies, which depend on the specific language and implementation, include:
| Question | Compiling ahead of time | Interpreting |
|---|---|---|
| When does translation happen? | Before the program runs | While the program runs |
| Quick experimenting? | Usually slower to iterate | Usually quicker to iterate |
| Distribution | Often one build per kind of machine | Same source with an interpreter per machine |
| Early error checking | Often more thorough | Some errors appear only when the line runs |
Speed is a frequent talking point, but this site avoids quoting benchmarks. What can be said safely is that the answer depends on the language, the implementation and the task, and that modern implementations are sophisticated enough that a rough rule can be misleading.
Hybrids and in-between designs
Real systems often combine the ideas. A popular technique translates source code into an intermediate form, sometimes called bytecode, which is then run by a virtual machine. That makes the same program portable across hardware, as an interpreter does, while still doing part of the translation in advance, as a compiler does. Some virtual machines also compile frequently used sections to machine code while the program is running, a technique known as just-in-time compilation.
This is why asking whether a particular language is “compiled” or “interpreted” is often less meaningful than it sounds. The language is a specification; compilers and interpreters are different ways of implementing it, and some languages have had both. Many scripting languages are run through interpreters or virtual machines, while languages used for systems programming are typically compiled.
Why it mattered historically
Automatic translation changed who could write programs. Once a compiler took on the tedious bookkeeping of registers and memory locations, programmers could think in terms of problems rather than machine details. Interpreters lowered the barrier even further by making the loop of write, run and fix very short.
The idea also supported portability. If a language is defined independently of a machine, then a compiler or interpreter for each new machine lets the same program run on both. That helped create a market for software that was not tied to a single manufacturer, and it is part of why modern software can be developed on one kind of computer for use on many others.