History

From Note G to WebAssembly

Two centuries of turning text into running programs: the first interpreters and compilers, the theory of grammars and automata, optimisers, virtual machines and JITs, and the browser as a compilation target. Filter by chapter to follow one thread.

1843 – 1951

Before compilers

Programs are written as numbers, or wired by hand. Then they start living in memory, and the first interpreters appear.

  1. 1843

    Note G

    Ada Lovelace

    In her notes on Babbage's Analytical Engine, Lovelace writes out step by step how the machine would compute Bernoulli numbers, often called the first published program.

    Read chapter 00 · Execution models →
  2. 1945

    The stored-program computer

    John von Neumann

    The First Draft of a Report on the EDVAC describes a machine whose program lives in memory alongside its data. Programs become data that other programs can write.

    Read chapter 06 · The runtime →
  3. 1949

    Short Code

    John Mauchly, William Schmitt

    Programmers write arithmetic expressions in a code that an interpreter carries out, at about fifty times the cost of machine code.

    Read chapter 00 · Execution models →
  4. 1951

    Regular events and finite automata

    Stephen Kleene

    Studying nerve nets, Kleene shows that regular expressions describe exactly what finite automata recognise: the theory behind every lexer.

    Read chapter 01 · Lexical analysis →

1952 – 1959

The first compilers

Translating formulas into machine code automatically, and convincing programmers that the result can be fast.

  1. 1952

    Autocode

    Alick Glennie

    For the Manchester Mark 1, often considered the first compiled programming language.

    Read chapter 00 · Execution models →
  2. 1952

    The A-0 system

    Grace Hopper

    Hopper's team at Remington Rand builds a system that assembles programs from a library of routines, and starts calling such tools “compilers”.

    Read chapter 00 · Execution models →
  3. 1956

    Three models for the description of language

    Noam Chomsky

    Chomsky classifies grammars by their power. Context-free grammars, one level above regular ones, become the standard way of describing programming languages.

    Read chapter 02 · Syntax analysis →
  4. 1957

    FORTRAN

    John Backus and his team at IBM

    The first FORTRAN compiler produces code nearly as fast as an expert's, and proves that high-level languages can be practical.

    Read chapter 05 · Optimisation →
  5. 1958

    Lisp and the first eval

    John McCarthy, Steve Russell

    McCarthy defines Lisp through a function that evaluates Lisp; Russell implements it on the IBM 704, creating the first Lisp interpreter.

    Read chapter 00 · Execution models →

1960 – 1979

Theory meets practice

Grammars, automata and types give compilers a mathematical foundation; Lex and Yacc make them easier to build.

  1. 1960

    The ALGOL 60 report and BNF

    John Backus, Peter Naur et al.

    The syntax of a programming language is defined precisely, for the first time, with a grammar notation: Backus–Naur form.

    Read chapter 02 · Syntax analysis →
  2. 1962

    A compiler that compiles itself

    Timothy Hart, Michael Levin

    The Lisp 1.5 compiler is written in Lisp: the first self-hosting compiler.

    Read chapter 00 · Execution models →
  3. 1965

    LR parsing

    Donald Knuth

    Knuth defines the grammars that can be parsed bottom-up, deterministically, reading left to right: the LR(k) family.

    Read chapter 02 · Syntax analysis →
  4. 1968

    From regular expressions to automata

    Ken Thompson

    Thompson's construction turns a regular expression into an automaton mechanically; it powers grep, editors and lexer generators.

    Read chapter 01 · Lexical analysis →
  5. 1969

    Principal types

    Roger Hindley

    Every expression of combinatory logic has a most general type that can be computed: the seed of type inference.

    Read chapter 03 · Semantic analysis →
  6. 1970

    Control flow analysis

    Frances Allen

    Basic blocks and control-flow graphs: the framework every optimiser still uses. With John Cocke she publishes the catalogue of optimising transformations a year later.

    Read chapter 05 · Optimisation →
  7. 1972

    C

    Dennis Ritchie

    A language close enough to the machine to write an operating system in. Unix is rewritten in C in 1973, and C becomes the portable assembler of the industry.

    Read chapter 00 · Execution models →
  8. 1973

    Top-down operator precedence

    Vaughan Pratt

    Binding powers instead of grammar levels: the expression-parsing method that Wahoo uses.

    Read chapter 02 · Syntax analysis →
  9. 1973

    A unified approach to optimisation

    Gary Kildall

    Data-flow analyses become instances of one iterative framework over the control-flow graph.

    Read chapter 05 · Optimisation →
  10. 1975

    Lex and Yacc

    Mike Lesk, Eric Schmidt, Stephen Johnson

    At Bell Labs, generators that write a lexer from regular expressions and an LALR parser from a grammar. Their descendants Flex and Bison are still used.

    Read chapter 01 · Lexical analysis →
  11. 1977

    UCSD Pascal and p-code

    Kenneth Bowles and students

    Pascal compiled to bytecode for a virtual machine runs on many microcomputers: “write once, run anywhere” twenty years before Java.

    Read chapter 06 · The runtime →
  12. 1978

    A theory of type polymorphism

    Robin Milner

    Algorithm W infers the most general types of a whole ML program without annotations. Haskell, OCaml and F# inherit it.

    Read chapter 03 · Semantic analysis →

1980 – 1994

Optimising and portable

Register allocation, SSA and free compilers; dynamic languages learn to compile themselves on the fly.

  1. 1981

    Register allocation by graph colouring

    Gregory Chaitin et al.

    Values that are alive at the same time cannot share a register: allocating registers becomes colouring a graph.

    Read chapter 04 · Code generation →
  2. 1984

    Reflections on Trusting Trust

    Ken Thompson

    A compiler can hide a back door in every program it compiles, including itself, leaving no trace in any source code.

    Read chapter 00 · Execution models →
  3. 1984

    Dynamic translation of Smalltalk

    Peter Deutsch, Allan Schiffman

    Bytecode is translated to machine code when a method is first called, and cached: an ancestor of just-in-time compilation.

    Read chapter 06 · The runtime →
  4. 1987

    GCC 1.0

    Richard Stallman

    A free, retargetable optimising C compiler. It grows into the GNU Compiler Collection.

    Read chapter 04 · Code generation →
  5. 1988

    Static single assignment

    Barry Rosen, Mark Wegman, Kenneth Zadeck

    Every variable assigned exactly once: the intermediate form that nearly every optimising compiler uses today.

    Read chapter 05 · Optimisation →
  6. 1991

    Polymorphic inline caches

    Urs Hölzle, Craig Chambers, David Ungar

    The Self project learns to optimise dynamic code from the types it actually sees: the techniques behind HotSpot and V8.

    Read chapter 06 · The runtime →
  7. 1991

    Python 0.9

    Guido van Rossum

    A dynamic language compiled to bytecode for a virtual machine, which becomes one of the most used languages in the world.

    Read chapter 00 · Execution models →

1995 – 2009

Virtual machines and JITs

Bytecode becomes mainstream with Java, and just-in-time compilers make dynamic languages fast.

  1. 1995

    Java and JavaScript

    James Gosling; Brendan Eich

    Java ships portable bytecode for the JVM; JavaScript, written in ten days, is interpreted inside Netscape Navigator.

    Read chapter 00 · Execution models →
  2. 1999

    HotSpot

    Sun Microsystems (from the Self and Strongtalk team)

    A JVM that interprets first and compiles only the hot methods, with optimisations based on what the program actually does.

    Read chapter 06 · The runtime →
  3. 2003

    LLVM 1.0

    Chris Lattner, Vikram Adve

    A reusable optimiser and back end around a well-defined SSA IR. Clang, Rust, Swift and Zig are built on it.

    Read chapter 04 · Code generation →
  4. 2004

    GCC drops its generated C++ parser

    GCC developers

    GCC 3.4 replaces its Bison grammar for C++ with a hand-written recursive-descent parser; the C front end follows in 2006.

    Read chapter 02 · Syntax analysis →
  5. 2008

    V8

    Lars Bak and the Chrome team

    JavaScript compiled straight to machine code makes web applications fast enough to replace desktop software.

    Read chapter 06 · The runtime →

2010 – today

The browser as a target

Compilers that compile themselves, languages that compile to JavaScript, and a portable bytecode for the web.

  1. 2011

    Rust compiles itself

    Graydon Hoare and the Rust team

    The Rust compiler, first written in OCaml, is rewritten in Rust and bootstraps itself. Rust 1.0 follows in 2015.

    Read chapter 00 · Execution models →
  2. 2012

    TypeScript

    Anders Hejlsberg (Microsoft)

    A typed language that compiles to JavaScript: the type checker catches errors, then the types are erased.

    Read chapter 00 · Execution models →
  3. 2013

    asm.js

    Luke Wagner, Alon Zakai, David Herman (Mozilla)

    A strict subset of JavaScript that engines can compile ahead of time shows that C and C++ can run in the browser at near-native speed.

    Read chapter 06 · The runtime →
  4. 2015

    Compiler errors for humans

    Evan Czaplicki

    Elm redesigns its error messages as plain explanations with suggestions; Rust and others follow, and Wahoo's messages copy the recipe.

    Read chapter 03 · Semantic analysis →
  5. 2015

    Go compiles itself

    The Go team

    Go 1.5 removes the last C from its compiler and runtime, translated to Go mostly by a program.

    Read chapter 00 · Execution models →
  6. 2017

    WebAssembly ships

    Mozilla, Google, Microsoft, Apple

    A portable, validated bytecode, designed together by all four browser makers, runs in Firefox, Chrome, Edge and Safari.

    Read chapter 06 · The runtime →
  7. 2018

    Tree-sitter

    Max Brunsfeld (GitHub)

    An incremental parser generator that re-parses code as you type and gives editors accurate syntax trees.

    Read chapter 02 · Syntax analysis →
  8. 2019

    WebAssembly becomes a W3C Recommendation

    W3C WebAssembly Working Group

    The fourth language of the web, after HTML, CSS and JavaScript.

    Read chapter 06 · The runtime →
  9. 2024

    A JIT for CPython

    Brandt Bucher and the CPython team

    Python 3.13 includes an experimental copy-and-patch JIT compiler, disabled by default: the reference Python starts compiling to machine code.

    Read chapter 00 · Execution models →
  10. 2026

    Wahoo

    This site

    A compiler from the Mushroom Kingdom to WebAssembly, written in Rust, running in your browser. Try it in the playground.