That transition happened with my the next big cluster of work, which was the work that I did at Berkeley, mostly as an undergraduate, on Project Genie: the 940 timesharing system and on the QED text editor. And I wrote an assembly-language debugger but I don’t remember much of anything about it.
The piece that had the most system flavor to it was the operating system. It’s not fair to say that I wrote the whole operating system; I didn’t. But I essentially wrote the whole kernel. This was done in assembly language. We’re talking about programs that are getting to be a little larger here, probably on the order of 10,000 lines of assembler. It had a process scheduler. It had virtual memory. It had a file system. In fact, it had several file systems.
There, there were more complex questions of data-structure design. The one that I remember is there was an active process table. And there was a question as to how to design that and how the operating system should decide when a process was runnable or not—that kind of thing. There were structures for keeping track of the virtual memory system. But some issues of interface started to emerge. Not within the operating system itself, because the operating system was so small that the kernel was designed essentially as a single piece, as a monolith.
But there were two important areas where issues of software interface started to emerge. One of them was simply the interface between user programs and the kernel. What should the system calls be? How should the parameters be laid out? I know that in the first few versions of the 940 TSS, the basic operations for reading and writing files were the equivalent of the Unix read and write calls, where you basically gave a base address and a count. Well, that was all very well and good, but a lot of the time that wasn’t what you wanted. You basically wanted a stream interface. And in those days, we didn’t have the concept that you could take an operating system facility and then wrap user-level code around it to give you some nicer interface in the way getc and putc get built on top of read and write. So what we actually did was in later versions of the operating system, we added operating-system calls that were the equivalent of getc and putc.
The other place where issues of interface started to show up were—again, based on the MULTICS mode—from the beginning we had a strong distinction between the kernel and what today we would call the shell. This was early enough in the development of operating systems that we didn’t realize that you could, in fact, build a shell with essentially no special privileges. The shell was a user-mode program, but it had a lot of special privileges. But there were some issues about what facilities the kernel had to give the shell—what things the shell should be able to do directly and what things it should have to make kernel calls for.
We saw interface-design choices just emerging from the task. That was the point in my career at which I dimly started to become aware that interfaces between entities really needed to be designed separately, that the interfaces between them were also an important design issue.
So responding to your question about whether the way I programmed in the small changed as I started to work with larger systems, the answer is, yes. As I built larger and larger systems, I found that when sitting down to write any piece of code, more and more the question I would ask myself first is, “OK, what’s the interface between this and everything around it going to look like? What gets passed in? What gets passed out? How much of a task should be on which side of an interface?” Those kinds of questions started to become a larger and larger part of what I was dealing with. And they did affect the way that I wrote individual smaller chunks of code, I think.
Seibel: And this was a natural consequence of working on bigger systems—eventually the systems get big enough that you just have to find some way to break them apart.
Deutsch: That’s right. In that sense I agree that software is fractal in that decomposition is an issue that happens at many different levels. I was going to say I don’t think that the kinds of decomposition at bigger grains are qualitatively the same as the kinds of decomposition that happen at smaller grains. I’m not sure. When you’re doing decomposition at a smaller grain you may not be thinking, for example, about resource allocation; when you’re doing decomposition at a larger grain you have to.
Seibel: Have you worked with people who, in your opinion, were very good programmers, yet who could only work at a certain scale? Like they could work well on problems up to a sort of certain size but beyond that, they just didn’t have the mentality for breaking systems apart and thinking about them that way?
Deutsch: I’ve worked with programmers who were very smart but who didn’t have experience at larger-scale programming. And for Ghostscript, I did have some pretty serious disagreements with two of the engineers who were brought into the team as it was getting handed over to the company that I started. Both very smart and hardworking guys, both experienced. I thought they were very good programmers, good designers. But they were not system thinkers. Not only were they not used to thinking in terms of the impact or ramifications of changes; they to some extent didn’t even realize that that was an essential question to ask. To me the distinction is between people who understand what the questions are that you have to ask in doing larger-scale design and the people who for whatever reason don’t see those questions as well.
Seibel: But you think those people—when they’re not trying to be the architect of a whole system—do good work?
Deutsch: Yeah. The two engineers that I’m thinking of both did really great work for the company. One of them was working on something that was large and rather thankless but important commercially. And the other one redid some substantial chunks of my graphics code and his code produces better-looking results. So these are good, smart, experienced guys. They just don’t kind of see that part of the picture—at least that’s my take on it.
Seibel: Are there particular skills that you feel made you a good programmer?
Deutsch: I’m going to give you a very new-age answer here. I’m not a newage kind of guy generally speaking, although I went through my period of really long hair. When I was at what I would consider the peak of my abilities, I had extremely trustworthy intuition. I would do things and they would just turn out right. Some of that was luck. Some of it, I’m sure, was experience that had simply gotten internalized so far down that I didn’t have conscious access to the process. But I think I just had a knack for it. I know that’s not a very satisfying answer but I truly believe that some of what made me good at what I did was something that was just there.
Seibel: In your days as a precocious teenager hanging out at MIT, did you have had a chance to observe, “Wow, this guy’s really smart but he doesn’t know how to do this thing that I know how to do.”?
Deutsch: No, I didn’t. Well, OK, I do remember when I started rewriting the text editor on Dennis’s PDP-1; I must have been 15 or 16. The original code had been written by one or two of the guys from the Tech Model Railroad Club group. Those were smart guys. And I looked at the code and I thought a lot of it was awful.
I would not say it was a difference between me and the people I was working around. It was a difference between the way I thought code should be and the code that I saw in front of me. I would hesitate to generalize that into a statement about the people.
I’ve always been really comfortable in what I would call the symbolic world, the world of symbols. Symbols and their patterns have always just been the stuff I eat for lunch. And for a lot of people that’s not the case. I see it even with my partner. We’re both musicians. We’re both composers. We’re both vocal performers. But I come at music primarily from a symbolic point of view. I do a lot of my composition just with a pencil and a pad of paper. The notes are in there but I’m not picking them out on the piano. I hear them and I have a plan.