The evolution of the compiler · the purple papers · VI

The hourglass

A compile has a shape. Your code climbs from flat text up into meaning, squeezes through one narrow universal neck, then descends into a specific machine. Many languages pour in the top; many machines catch at the bottom; everything passes through the same load-bearing 0 in the middle.

top: languages fall in neck: the IR · 0 bottom: machines catch

Ascend · 0 · descend

RAISING → IR → LOWERING

Two slopes meet at the neck. Up the front you climb into meaning; down the back you fall into machine. They mirror each other in shape but not in nature — and the tree you climbed turns into a graph on the way down.

↑ front slope — raising

Climb into meaning

Start at the bottom: flat characters, print("hi"). Group them into words, build them into a tree, ascend toward the most abstract, best-understood form — the point where the compiler finally knows what you meant. Lossless, deterministic, a clean funnel.

text → tokens → parse tree → IR
shape: a tree (decomposition)
↓ back slope — lowering

Fall into machine

From the neck, descend toward one specific chip: IR → optimized IR → assembly → machine code → micro-ops. But here the optimizer rolls downhill on a cost surface, choosing the cheapest path — a gradient-style search. So the descent is lumpy where the climb was smooth.

IR → optimize → assembly → machine
shape: a graph (dependencies)

You climb a tree and descend a graph — and the shape changes exactly at the neck, because going up is decomposition (always a tree) and coming down requires dependency (always a graph). List → tree → graph, all in one compile.

Why the neck is thin

THE NARROW-WAIST PRINCIPLE

The thinness is the whole point. One universal middle is what lets both ends be wide and various — and it's what kills the combinatorial explosion.

N × M
without a shared neck:
every language needs its own translator to every machine.
5 languages × 5 machines = 25 whole compilers.
N + M
with one IR at the waist:
5 front-ends + 5 back-ends, all meeting at the neck.
= 10 pieces. the thin middle is the feature.

the internet

thousands of apps above, thousands of networks below — one skinny waist, IP, that everything crosses.

the cell

thousands of genes up top, thousands of functions below — one waist, the genetic code the ribosome reads.

the compiler

many languages, many chips — one waist, the IR. it's why LLVM exists, and why it won.

The root · 1823

WHERE THE TOWER STARTS

Every floor of this hourglass — the whole idea of a machine that runs programs — traces back to one engine and the first person to write code for it.

Charles Babbage

1791–1871 · the engine

In 1823 the British government funded his Difference Engine — arguably the first public money ever spent on a computer. He went on to design the Analytical Engine: a general machine that could be programmed, borrowing punched cards from the Jacquard loom. The hardware the whole tower stands on.

Ada Lovelace

1815–1852 · the program

His collaborator — not his wife. In 1843, translating an account of the Analytical Engine, she added notes containing the first published algorithm and the leap no one else made: that the machine could manipulate any symbols, not just numbers — music, logic, anything. That's the seed of the programs a compiler feeds.

On the "stole it from his wife" version: Ada wasn't his wife (his wife, Georgiana, died in 1827, unrelated to the machines), and it was 1843, not 1823. The credit is a genuine two-sided fight: some historians say her Notes were written under Babbage's supervision and reflect his understanding; others credit her with the real conceptual jump. She's one of the rare cases that's been both over- and under-credited — so the honest verdict isn't "robbed," it's "still argued about."