IDE Toolkit

Room 1 · Green Screens

When the Compiler Did Not Make You Wait

Compilation as Interruption, and Then as Background

Python code on a dark screen showing a script parsing JSON event data

Source on screen, one change at a time.

Photo: Nemuel Sereti / Pexels

Before the integrated editor changed the rhythm of programming, compilation was an event — something a developer triggered, waited through, and returned from. Batch systems measured that wait in minutes; on a time-shared mainframe, longer. The interactive IDE made a different promise: that the machine would keep up with the typist.

The engineering argument behind that promise was incremental compilation — the strategy of reprocessing only the source units that had changed since the last build, rather than walking the entire program again. The idea arrived before graphical interfaces did. Interlisp, the Lisp environment developed at Xerox PARC in the early 1970s, treated the program as a live collection of function definitions; redefining a function replaced it in memory without disturbing the rest. The REPL was already performing a kind of unit-granularity recompilation on every evaluated expression.

Vintage Power Macintosh tower computer with CRT monitor, keyboard, and external drives on display

Period hardware on a museum plinth — the class of machine these compilers were sized for.

Photo: Ruben Boekeloo / Pexels

The tradeoff was dependency tracking. A compiler that rebuilds only the changed unit must also know which other units depend on it, and must decide whether to propagate recompilation outward. Get that dependency graph wrong and the executable is silently inconsistent — the classic hazard of partial builds. Interlisp sidestepped the problem because Lisp functions are largely self-contained at the symbol level; a language with static types and header files offered no such convenience.

Turbo Pascal's single-pass compiler, written by Anders Hejlsberg and shipped by Borland in 1983 at $49.95, solved the wait problem by a different route: it was simply fast enough that the whole program compiled before the feeling of delay set in. On the hardware of 1983, a complete recompile finishing in seconds was subjectively indistinguishable from an incremental one. The resident, memory-mapped design — the compiler, editor and linker sharing one process — eliminated the process-launch overhead that made other compilers feel slow before a single token was scanned.

Later IDEs had to confront incrementalism directly as programs grew. The Java tools inside Eclipse, released by IBM in 2001, maintained an in-memory model of the type system and recompiled affected compilation units on save — surfacing errors in the editor margin without a full build. That background incremental compiler, developed by the Eclipse Java Development Tools team, became the template for how a statically typed IDE could remain interactive at scale.

The underlying tension — between compile-everything simplicity and recompile-only-what-changed precision — was never fully resolved, only managed. Each generation of tools found a new point on that curve, shaped by the language, the hardware and what developers were willing to tolerate between a keystroke and a result.