Levels of Abstraction
Wysiwyg is an example of a layer of abstraction–a higher-level tool that allows computer users to ignore some lower-level complexity. Programmers use abstractions all the time. The text code written in a programming language is an abstraction of the machine code that a computer actually understands. A Web domain name is an abstraction of a server’s numerical Internet Protocol address.
But most of the layers of abstraction in computer systems are less visible and more arcane than Wysiwyg. Ever since programmers stopped memorizing the opcodes that Simonyi used in his youth, they have been layering new abstractions upon older abstractions. Every generation of programmers uses its era’s programming languages and tools to build the programs of the next generation. Layers of abstraction have accumulated like geological strata. Messages are constantly racing up from the binary bedrock of your machine and back down again, making it possible for a mouse-click to accomplish its function. Your mouse-click triggers some code in the operating system, which sends a message to the word processing program, which instructs the operating system to save your file to a hard drive. But that apparently simple process is possible only because of many, many layers of abstraction.
The history of software is the history of these layers, each of them lifting programmers farther from the binary, leaving them better able to coax computers into performing useful tasks. Steadily, programmers gained more power. But they were also tackling ever more ambitious problems. Programs ballooned in size, and programmers started getting lost in tangles of what they called “spaghetti code,” which proved impossible to unravel and repair. Thus, large software projects became epics of frustration and delay. Program managers faced business problems like, How do you realistically schedule a project? How do you improve individual productivity? How do you coördinate complex work across a large team? Each of these questions proved surprisingly difficult to answer.
The difficulty of coördinating a team’s work inspired software engineering’s most famous dictum, known as Brooks’s Law: “Adding manpower to a late software project makes it later.” Frederick P. Brooks Jr. reached this gloomy conclusion after leading IBM’s troubled effort to write software for its 360 mainframes in the 1960s. In his 1975 book, The Mythical Man-Month , Brooks observed that work proceeds slower on bigger teams because of “coördination costs”–the time programmers lose keeping one another apprised of their work.
This was the backdrop for Simonyi’s 1977 dissertation, “Meta-Programming: A Software Production Method.” Simonyi proposed a new approach to “optimizing productivity,” in which one lead programmer, or “meta-programmer,” designed a product and defined all its terms, then handed off a blueprint to “technicians,” worker-bee programmers who would do the implementation. Simonyi aimed to escape Brooks’s Law by forbidding the technicians to talk with one another: all communication had to pass through the meta-programmer. For his dissertation, he tested the idea using two groups on two projects, A and B. His despotic approach to programming never caught on, but that hardly troubled him. Simonyi’s chief goal in researching his dissertation wasn’t to prove the value of his ideas but to get Bravo, the new Wysiwyg word processor, written faster. He couldn’t persuade the PARC brass to hire additional programmers, so he used his dissertation as a subterfuge to bring in some help. Bravo itself was project B.