One of the wonderful things about working at MIT was that there was a lot of code sitting around that was not kept under lock and key, written by pretty smart hackers. So I read the ITS operating system. I read the implementations of TECO and of Lisp. And the first pretty printer for Lisp, written by Bill Gosper. In fact I read them as a high-school student and then proceeded to replicate some of that in my 1130 implementation.
I would not have been able to implement Lisp for an 1130 without having had access to existing implementations of Lisp on another computer. I wouldn’t have known what to do. That was an important part of my education. Part of the problem that we face nowadays, now that software has become valuable and most software of any size is commercial, is that we don’t have a lot of examples of good code to read. The open source movement has helped to rectify that to some extent. You can go in and read the source to Linux, if you want to. Reading the source to TeX was a valuable exercise just because it was a large body of well-thought-out, well-debugged code.
Seibel: I usually have the best luck reading code when I have a very specific need to know how something works; what is your mindset reading a program like TeX?
Steele: Sometimes I’ve got a specific goal because I’m trying to solve a problem. There have been exactly two times, I think, that I was not able to fix a bug in my TeX macros by reading The TeXbook and it was necessary to go ahead and read TeX: The Program to find out exactly how a feature worked. In each case I was able to find my answer in 15 minutes because TeX: The Program is so well documented and cross-referenced. That, in itself, is an eye-opener—the fact that a program can be so organized and so documented, so indexed, that you can find something quickly.
The other thing I learned from it is how a master programmer organizes data structures, how he organizes the code so as to make it easier to read. Knuth carefully laid out TeX: The Program so you could almost read it as a novel or something. You could read it in a linear pass. You’d probably want to do some jumping back and forth as you encountered various things. Of course, it was an enormous amount of work on his part, which is why very few programs have been done that way.
Seibel: And when you get to the end, what are you going to take away?
Steele: I’ll have a pretty good idea of how it’s organized and I may have come away with some ideas about how to organize my own code better. I don’t think I’ll ever be able to write in the style of Knuth any more than I could write in the style of Faulkner or Hemingway. Nevertheless, having read novels by those writers will influence my own thinking about English style a little bit. Maybe I’ll make a conscious decision not to write like Hemingway for some reason or another. It’s a valuable experience. Not to mention just the enjoyment of going through a well-written novel or a wellwritten piece of code.
Seibel: Have you ever written literate programs?
Steele: Not in nearly the disciplined way that Knuth has. It has influenced my style in that I think about those issues—I will often actually write a paragraph of prose before beginning to write a subroutine. But I don’t do it in nearly as disciplined a style. And sometimes I wonder whether he does, either, when he’s doing exploratory programming before he readies it up for publication. I don’t know what his process looks like there.
Seibel: So you’ve tried it but it didn’t strike you as something that made programming much more productive or enjoyable?
Steele: In part I didn’t feel like doing a lot of tool building for myself. The tools he had built were organized around Pascal and then C. Pascal I could see but I was quite aware of the flaws in C and I wasn’t sure that using literate programming tools would suffice to overcome them. If he had built literate programming tools for Common Lisp I might have jumped over to them much more quickly.
Seibel: Leaving aside literate programs and back to reading code, do you find that you can read usually well-written programs from beginning to end? Or is it always a hypertext that you have to find your way through?
Steele: I don’t necessarily object to hypertext. But I think if a program is well written, there will be something about its structure that will guide me to various parts of it in an order that will make some kind of sense. You know, it’s not just what the program does—there’s a story. There’s a story about how the program is organized, there’s a story about the context in which the program is expected to operate. And one would hope that there will be something about the program, whether it’s block comments at the start of each routine or an overview document that comes separately or just choices of variable names that will somehow convey those stories to you. And one would hope that a good programmer, a really good programmer, will have given thought to conveying those stories in addition to the story of what the program actually does.
Seibel: What code have you read most recently just for fun?
Steele: It’s hard to find good code that’s worth reading. We haven’t developed a body of accepted literature that says, “This is great code; everybody should read this.” So it tends to be one-page snippets, often in papers, rather than chunks of code out of existing stuff. Probably the code I’ve read most recently is the stuff that my own team has been producing as part of the Fortress implementation. And parts of the Java libraries.
Probably the last substantial body of code I read just for fun was written by George Hart. He’s a mathematician, a specialist in polyhedra. And he has a very interesting piece of code that will generate and display complex polyhedra using VRML within a browser. And so he’s got this enormous body of JavaScript code that constructs VRML code and then feeds that to the VRML displayer.
I decided to try to enhance it in various ways so I went in and read his code thoroughly. And then proceeded to try to make various enhancements to it and understand what was going on: try to make some somewhat funkier polyhedra and so forth. I also managed to make several bad errors—there was a relaxation algorithm that tries to spread out the vertexes of the polyhedra to make it prettier and easier to display, and occasionally I’d introduce mathematical instabilities which would cause grotesque things to happen. Tremendous fun, and I was doing this purely for my own edification. That was probably six or seven years ago.
Seibel: How much did the reading and the modification intertwine? Can you read sitting at a table with a printout or at a computer without executing it to see what happens if you twiddle that little bit there?
Steele: Well I did, in fact, print out the code on paper. I would sit at a desk and read it. And very often mark it up and make annotations and ask myself questions and things like that. And then I’d go back to the computer and start typing in things and see how it behaved. And tracing it.
Seibel: In this case you wanted to modify it, so that’s what you did. But could you get some benefit or enjoyment out of just reading the code? Print it out, read it, maybe scribble some questions on it, and then put it down?
Steele: Yes. If I had stopped at that point, it would have been a worthwhile exercise, just having read the code. It taught me something about VRML; it taught me something about JavaScript, which is that it doesn’t have as many abstractions as I would like. The dynamic typing was a little bit too freeform for my taste—in an object-oriented language.
Seibel: So let’s talk a little bit about designing software. You’re not coding as much these days as you used to, but how did you go about designing a new piece of software? Do you sit down at a computer and start coding or do you sit with a pad of graph paper, or what?