Stuart Feldman Knew Make’s Tab Rule Was a Bad Idea. He Kept It Because About a Dozen People Used It.

Front panel of a DEC PDP-11/70 minicomputer tinted blueprint blue, beside the name “Stuart Feldman”, a small dependency graph and the line “Make · Bell Labs, 1976”.


Around 1976 at Bell Labs, Stuart Feldman wrote Make, the Unix tool that rebuilds only what a change affects, and gave it a rule about tab characters that still trips up programmers. He knew the rule was a bad idea, he said later, but kept it because within a few weeks about a dozen people were already using his tool.

Make began with someone else’s bad morning. In Feldman’s account, Steve Johnson, the author of the parser generator yacc, came “storming into my office, cursing the Fates that had caused him to waste a morning debugging a correct program.” Johnson had already fixed the bug. But the fixed file had not been recompiled, so the program he kept testing was still built from the old code.

Feldman knew the feeling. He had spent part of the previous evening “coping with the same disaster” on a project of his own. The tool, he recalled, “began with an elaborate idea of a dependency analyzer, boiled down to something much simpler, and turned into Make that weekend.”

Why programmers kept debugging code that was already fixed

Any sizable program was split across many source files. Each file was compiled into an object file, and the object files were linked into the finished program. Edit a source file and forget to recompile it, and the link step simply reuses the old object file. As Feldman’s 1978 paper on Make put it, “it is easy to lose track of which files need to be reprocessed or recompiled after a change is made.”

In a 1989 interview with the historian Michael Mahoney, Feldman described writing a program of three or four thousand lines in Ratfor, a structured dialect of Fortran, and said he “kept making the classic error of debugging a correct program.” His defense was brute force: before driving home, he would “recompile the whole world in the background.”

How Make decides what to rebuild

Make replaced the programmer’s memory with a description file, today usually called a makefile. In it, a programmer lists each file a program needs, what that file depends on, and the commands that build it. Make then checks modification times. If a file is older than anything it depends on, Make reruns its commands; if not, Make leaves it alone.

Feldman’s 1978 paper summed up the design in one sentence: “The description file really defines the graph of dependencies; Make does a depth-first search of this graph to determine what work is really necessary.” Built-in rules, such as how to turn a C source file into an object file, meant many dependencies did not have to be written down at all. The paper also thanks Steve Johnson “for suggesting this approach to program maintenance control.”

The tab rule Feldman kept for about a dozen users

The 1978 paper spelled out the syntax. Commands could appear “after a semicolon on a dependency line or on lines beginning with a tab immediately following a dependency line.”

Feldman later explained where the tab came from. Johnson’s yacc was new, and Lex, a tool that generates code for recognizing patterns in text, was “brand new.” He saw Make as a good excuse to learn them. “After getting myself snarled up with my first stab at Lex, I just did something simple with the pattern newline-tab. It worked, it stayed.”

Then came the decision that made the shortcut stick. “And then a few weeks later I had a user population of about a dozen, most of them friends, and I didn’t want to screw up my embedded base. The rest, sadly, is history.”

That account appears in Eric S. Raymond’s 2003 book The Art of Unix Programming. In 2015, Michael Stillwell emailed Feldman about a version he had heard: an early user complained about the tab and was told it was too late to change. Feldman replied that the story was “only partly true.”

He had used tabs because he “had trouble with some other patterns” in the first version of Lex. Within a few weeks, a dozen friends were using Make, “so even though I knew that ‘tab in column 1’ was a bad idea, I didn’t want to disrupt my user base. So instead I wrought havoc on tens of millions.”

What the weekend story leaves out

Feldman’s “that weekend” describes only the first version. In the 1989 interview, he said that “after a week or two, I rewrote the entire thing.” Make kept changing after that. The version log in its source code opens with “2.1 4/24/76 Base version,” and the copy that shipped with Version 7 Unix in 1979 is version 2.58.

Before Version 7, a version of Make dated April 1977 had already reached the Programmer’s Workbench (PWB), a Unix distribution for software development groups inside the Bell System. Doug McIlroy, who led the Bell Labs research department where Unix was created, put it plainly: “PWB did not create make; Stu Feldman did it in research.”

Why a 1976 shortcut still shows up in error messages

The flaw is easy to state. A tab and a run of spaces can look identical on screen, so, as Raymond wrote, “the interpretation of a makefile can change drastically on the basis of invisible differences in whitespace.” He called the rule “one of the worst design botches in the history of Unix.”

GNU Make, the GNU Project’s version of the tool, still enforces it. Its manual calls the commands a recipe and says every recipe line “must begin with a tab character,” adding: “Eight spaces do not count.” Indent a recipe with eight spaces instead of a tab, and GNU Make typically stops with “missing separator (did you mean TAB instead of 8 spaces?).” Only in 2010, with version 3.82, did GNU Make add a setting, .RECIPEPREFIX, that lets a makefile use a different character.

The rule did not stop Make from spreading. The Association for Computing Machinery (ACM) gave Feldman its 2003 Software System Award for Make, noting that “there is probably no large software system in the world today that has not been processed by a version or offspring of Make.” After Bell Labs, Feldman held senior research and engineering roles at Bellcore, IBM and Google, and served as ACM president from 2006 to 2008. He has used the tab as an example in software engineering lectures.

What the tab rule shows about early design decisions

Feldman did not choose the tab after weighing alternatives. He took the pattern that worked while he was struggling with an early version of Lex, and within a few weeks the cost of changing it no longer fell on him alone. A design stops being a draft once other people depend on it, and for Make that took about a dozen friends.

Johnson’s lost morning gave Unix a tool that works out what needs rebuilding. Feldman’s struggle with Lex gave that tool a rule that GNU Make still enforces by default fifty years later. When the ACM honored him for Make, his one-minute talk on stage began: “I would like to apologize.”

Related stories

Sources

Share this article
FacebookThreadsLinkedInX

Leave a Reply

Your email address will not be published. Required fields are marked *