176 Programming The designers of the Interlisp environment had a completely different approach. They decided to develop large sophisticated tools that took a long time to learn how to use. The payoff for investing the time to use the tools would be that the programmer who learned the tools would be more productive for it. That seems reasonable. Sadly, few programmers of today’s machines know what it is like to use such an environment, in all its glory. Programming in Plato’s Cave I got the impression that the objective [of computer language design and tool development] was to lift everyone to the highest productivity level, not the lowest or median. —From a posting to comp.lang.c++ This has not been true of other industries that have become exten- sively automated. When people walk into a modern automated fast- food restaurant, they expect consistency, not haute cuisine. Consis- tent mediocrity, delivered on a large scale, is much more profitable than anything on a small scale, no matter how efficient it might be. —Response to the netnews message by a member of the technical staff of an unnamed company.1 Unix is not the world’s best software environment—it is not even a good one. The Unix programming tools are meager and hard to use most PC debuggers put most Unix debuggers to shame interpreters remain the play toy of the very rich and change logs and audit trails are recorded at the whim of the person being audited. Yet somehow Unix maintains its reputa- tion as a programmer’s dream. Maybe it lets programmers dream about being productive, rather than letting them actually be productive. 1This person wrote to us saying: “Apparently a message I posted on comp.lang.c++ was relayed to the UNIX-HATERS mailing list. If I had known that, I would not have posted it in the first place. I definitely do not want my name, or anything I have written, associated with anything with the title ‘UNIX-HATERS.’ The risk that people will misuse it is just too large.… You may use the quote, but not my name or affiliation.”
Programming in Plato’s Cave 177 Unix programmers are like mathematicians. It’s a curious phenomenon we call “Programming by Implication.” Once we were talking to a Unix pro- grammer about how nice it would be to have a utility that could examine a program and then answer questions such as: “What functions call function foo?” or “Which functions modify the global variable bar?” He agreed that it would be useful and then observed that, “You could write a program like that.” To be fair, the reason he said “You could write a program like that” instead of actually writing the program is that some properties of the C language and the Unix “Programming Environment” combine synergistically to make writing such a utility a pain of epic proportion. You may think we exaggerate, and that this utility could be easily imple- mented by writing a number of small utility programs and then piping them together, but we’re not, and it can’t. Parsing with yacc “Yacc” was what I felt like doing after I learned how to use yacc(1). —Anonymous “YACC” stands for Yet Another Compiler Compiler. It takes a context- free grammar describing a language to be parsed and computes a state machine for a universal pushdown automaton. When the state machine is run, one gets a parser for the language. The theory is well understood since one of the big research problems in the olden days of computer science was reducing the time it took to write compilers. This scheme has one small problem: most programming languages are not context-free. Thus, yacc users must specify code fragments to be run at certain state transitions to handle the cases where context-free grammars blow up. (Type checking is usually done this way.) Most C compilers today have a yacc-generated parser the yacc grammar for GCC 2.1 (an otherwise fine compiler written by the Free Software Foundation) is about 1650 lines long. The actual code output by yacc and the code for the uni- versal pushdown automaton that runs the yacc output are much larger. Some programming languages are easier to parse. Lisp, for example, can be parsed by a recursive-descent parser. “Recursive-descent” is computer jargon for “simple enough to write on a liter of Coke.” As an experiment,
Previous Page Next Page