Compiler

A program that reads your entire source code and translates it into machine code before the program runs — producing a standalone executable that the processor can run directly, without needing the original source code or the compiler itself.


What is it?

When you write code in C, Rust, or Go, you cannot run it directly. The processor does not understand these languages — it only understands machine-code. Something needs to translate your human-readable code into the binary patterns the CPU reads.

A compiler does this translation in advance. It reads your entire program, analyses it, optimises it, and produces a standalone executable file. Once compiled, the executable runs on its own — no compiler needed, no source code needed.1

This is fundamentally different from an interpreter, which translates and executes code line by line at runtime. The compiler does all the work up front. The interpreter does it on the fly.

The first widely used compiler was created by John Backus at IBM in 1957 for FORTRAN. Before compilers, programmers wrote machine code by hand — what Backus described as “hand-to-hand combat with the machine.”2

In plain terms

A compiler is a book translator. You give them the entire manuscript in French. They work through it, translate every page, and hand you a finished English book. You can read the English version whenever you want without needing the translator again.


At a glance


How does it work?

The compilation pipeline

A compiler works in stages, each transforming the code into a form closer to machine code:3

1. Lexical analysis. The compiler reads your source code character by character and groups them into tokens — keywords (if, while), identifiers (variable names), operators (+, =), literals (42, "hello"). Like breaking a sentence into words.

2. Parsing. The tokens are organised into a tree structure (abstract syntax tree) that represents the grammar of your program. Like diagramming a sentence to understand its structure.

3. Semantic analysis. The compiler checks that the code makes sense — types match, variables are declared before use, functions receive the right number of arguments. Errors found here are compile-time errors.

4. Optimisation. The compiler rewrites parts of the program to make it faster or use less memory, without changing what it does. This is one of the major advantages of compilation — the compiler has time to find improvements a human would miss.4

5. Code generation. The optimised representation is translated into machine code for the target processor.

Think of it like...

A professional editor. They read your entire manuscript (lexical analysis), understand its structure (parsing), check for logical errors (semantic analysis), improve the prose (optimisation), and produce the final published version (code generation).

Compile-time vs runtime

This distinction matters. Compile-time is when the compiler runs — before your program executes. Runtime is when your program runs.

Errors caught at compile-time (type mismatches, missing semicolons, undeclared variables) are caught before anyone uses your program. This is a safety advantage — the compiler catches entire categories of bugs that an interpreted language would only discover when the problematic line executes.5

Cross-compilation

A compiler can produce machine code for a processor different from the one it runs on. This is cross-compilation — you compile on your laptop (x86) to produce code that runs on a phone (ARM) or an embedded device. The compiler contains the knowledge of both instruction sets.6


Why do we use it?

Key reasons

1. Performance. Compiled code runs directly on the CPU with no translation overhead. C and Rust programs typically run 10-100x faster than equivalent Python or Ruby programs.7

2. Early error detection. The compiler catches errors before the program runs — type mismatches, syntax errors, unreachable code. Bugs found at compile-time are cheaper to fix than bugs found in production.

3. Standalone distribution. The compiled executable does not need the source code, the compiler, or any runtime to execute. You can distribute a single file.

4. Optimisation. The compiler applies sophisticated transformations — inlining functions, eliminating dead code, reordering instructions — that a human would not do by hand.


When do we use it?

  • When performance matters — system software, game engines, real-time applications
  • When distributing software to users who should not need to install a language runtime
  • When the codebase is large and early error detection saves time
  • When targeting embedded devices or hardware with limited resources

Rule of thumb

If execution speed or safety is critical, use a compiled language. If development speed or flexibility is critical, an interpreted language may be the better choice. Many projects use both — Python for prototyping, C for performance-critical sections.


How can I think about it?

The book translator

A compiler is like hiring a translator to translate an entire book. You hand them the French manuscript. They spend time working through it — checking grammar, resolving ambiguities, polishing the prose. Then they deliver a finished English book.

The reader never sees the French original. The reader never meets the translator. They just read the book. If the original had typos, the translator caught them during the process. If a sentence was awkward, the translator improved it (optimisation).

The factory vs the workshop

A compiler is like a factory. You design the product blueprint (source code), the factory processes it through assembly lines (compilation stages), and produces finished goods (executable) at the end. The setup takes time, but once running, the output is fast and consistent.

An interpreter is like a workshop — each piece is made by hand, one at a time. More flexible, but slower for mass production.


Concepts to explore next

ConceptWhat it coversStatus
interpreterThe alternative: translating line by line at runtimecomplete
machine-codeWhat the compiler producescomplete
runtimeThe environment where compiled programs executecomplete
abstraction-layersCompilers as a bridge between abstraction levelscomplete

Check your understanding


Where this concept fits

Position in the knowledge graph

graph TD
    AL[Abstraction Layers] --> COMP[Compiler]
    AL --> INTP[Interpreter]
    AL --> MC[Machine Code]
    COMP -->|produces| MC
    COMP -.->|compare with| INTP

    style COMP fill:#4a9ede,color:#fff

Related concepts:

  • interpreter — the alternative translation strategy, executing line by line instead of translating everything first
  • machine-code — the output a compiler produces
  • runtime — the environment where the compiled program executes

Sources


Further reading

Resources

Footnotes

  1. Aho, A. et al. (2006). Compilers: Principles, Techniques, and Tools. 2nd ed. Addison-Wesley. Known as “the Dragon Book” — the standard reference on compiler design.

  2. IBM. (2026). John Backus. IBM History.

  3. Appel, A. (2004). Modern Compiler Implementation in C. Cambridge University Press.

  4. Compiler optimisations can improve performance by 2-10x over naive code generation. Muchnick, S. (1997). Advanced Compiler Design and Implementation. Morgan Kaufmann.

  5. Pierce, B. (2002). Types and Programming Languages. MIT Press.

  6. Wikipedia. (2026). Cross compiler. Wikipedia.

  7. Benchmarks Game. (2026). Computer Language Benchmarks Game. Debian.