I think it was 1971. The bug didn’t really bite me until a couple years later. And what did it, of course, was timesharing.
 That said, I don’t think all those concepts are good. OO is a funny thing. It means two things. It means modularity. And modularity is great. But I don’t think the OO people can claim the right to that. You can look at older literature—for example Parnas’s information hiding—and see that the notion of a kind of class as an abstraction predates object-oriented programming. And the other thing is inheritance and I consider inheritance a mixed blessing, as many people do by now.
 The older I get, the more I realize it isn’t just about making it work; it’s about producing an artifact that is readable, maintainable, and efficient. Generally speaking, I find that, contrary to popular belief, the cleaner and nicer the program, the faster it’s going to run. And if it doesn’t, it’ll be easy to make it fast. As they say, it’s easier to optimize correct code than to correct optimized code.
 It’s like if the only tool you have is a hammer and someone gives you a screwdriver, and you say, “Well, this isn’t a very good hammer but I guess I can hold the blade in my hand and whack with the handle.”
 I don’t know. But when you choose a language, you’re choosing more than a set of technical trade-offs—you’re choosing a community. It’s like choosing a bar. Yes, you want to go to a bar that serves good drinks, but that’s not the most important thing. It’s who hangs out there and what they talk about. And that’s the way you choose computer languages. Over time the community builds up around the language—not only the people, but the software artifacts: tools, libraries, and so forth.
 You mentioned calculus—I think it’s less important. A funny thing has happened over the years. It used to be just assumed that if you were an educated person who had gone to college you had to know calculus. And there are a lot of beautiful ideas there—it’s nice to be able to get your mind around infinity in that way. But there’s a discrete and a continuous way to get your mind around infinity. I think that for a programmer it’s more important to have mastered the discrete way. For example, I just mentioned induction proofs. You can prove something true for all integers. It’s kind of magical. You prove it for one integer and you prove that one implies the next and then you’ve proved it for all of them. And I think that is more important for a programmer than, let’s say, understanding the notion of limits.
 Thelonious Monk: “Simple ain’t easy.”
 Modern IDEs are great for large-scale refactorings. Something that Brian Goetz pointed out is that people write much cleaner code now because they do refactorings that they simply wouldn’t have attempted Joshua Bloch 187 before. They can pretty much count on these tools to propagate changes without changing the behavior of the code.
 There’s a wonderful Knuth quote about testing, quoted by Bentley and McIlroy in their wonderful paper called “Engineering a Sort Function,” about getting yourself in the meanest and nastiest mood that you can.
 This is an example of why you need safe languages. This is just not something that anyone should ever have to cope with. I was talking to someone recently at a university who asked me what I thought about the fact that his university wanted to teach C and C++ first and then Java, because they thought that programmers should understand the system “all the way down.” I think the premise is right but the conclusion is wrong. Yes, students should learn low-level languages. In fact, they should learn assembly language, and even chip architecture. Though chips have turned into to these unbelievable complicated beasts where even the chips don’t have good performance models anymore because of the fact that they are such complicated state machines. But they’ll be much better high-level language programmers if they understand what’s going on in the lower layers of the system. So yes, I think it’s important that you learn all this stuff. But do I think you should start with a low-level language like C? No! Students should not have to deal with buffer overruns, manual memory allocation, and the like in their first exposure to programming.
 There’s a brilliant quote by Tony Hoare in his Turing Award speech about how there are two ways to design a system: “One way is to make it so simple that there are obviously no deficiencies and the other way is to make it so complicated that there are no obvious deficiencies.”
 I think that it would be fun to just take a couple of months and work my way through Structure and Interpretation of Computer Programs with my son.
 It still only had line editors. It didn’t have full-screen editors. And all your programs had to be in one directory. Ten letters for the file name and three letters for the extension. And a Fortran compiler or assembler and that’s it. The funny thing is, thinking back, I don’t think all these modern gizmos actually make you any more productive. Hierarchical file systems—how do they make you more productive? Most of software development goes on in your head anyway. I think having worked with that simpler system imposes a kind of disciplined way of thinking. If you haven’t got a directory system and you have to put all the files in one directory, you have to be fairly disciplined. If you haven’t got a revision control system, you have to be fairly disciplined. Given that you apply that discipline to what you’re doing it doesn’t seem to me to be any better to have hierarchical file systems and revision control. They don’t solve the fundamental problem of solving your problem. They probably make it easier for groups of people to work together. For individuals I don’t see any difference.
 I think the lack of reusability comes in object-oriented languages, not in functional languages. Because the problem with object- oriented languages is they’ve got all this implicit environment that they carry around with them. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle. If you have referentially transparent code, if you have pure functions—all the data comes in its input arguments and everything goes out and leaves no state behind—it’s incredibly reusable.
 Programmers have been conned into using all these different programming languages and they’ve been conned into not using easy ways to connect programs together. The Unix pipe mechanism—A pipe B pipe C—is trivially easy to connect things together. Is that how programmers connect things together? No. They use APIs and they link them into the same memory space, which is appallingly difficult and isn’t cross-language. If the language is in the same family it’s OK—if they’re imperative languages, that’s fine. But suppose one is Prolog and the other is C. They have a completely different view of the world, how you handle memory. So you can’t just link them together like that. You can’t reuse things. There must be big commercial interests for whom it is very desirable that stuff won’t work together. It creates thousands of jobs for consultants. And thousands of tools to solve problems that shouldn’t exist. Problems that were solved years ago. I think it’s really weird that we have very few programming languages that describe the interaction between things. I keep coming back to ways of gluing things together and ways of describing protocols. We don’t have ways of describing this protocol in between things: if I send you one of them then you send me one of these. We have ways of describing packets and their types but we have very restricted ways of describing the protocols. Programming is fundamentally different to the way we construct things in the real world. Imagine you’re a car manufacturer. You buy components Joe Armstrong 214 from subcontractors. You buy a battery from Lucas and you buy a generator from somewhere. And you bolt things together—you construct things by placing things next to each other. You build a house by putting the bricks on top of each other and putting the door there. That’s how we make chips. You get a printed circuit board that basically just provides this connection. But you can think of making electronic things as you buy all these chips and you connect the legs of some to others with wires. And that’s how you make hardware. But we don’t make software like that. We should make software like that and we don’t. The reason we don’t, has to do with concurrency. You see, the chips, when you put them next to each other, they all execute in parallel. And they send messages. They are based on this message-passing paradigm of programming, which is what I believe in. And that’s not how we write software together. So I think one direction Erlang might take, or I would like it to take, is this component direction. I haven’t done it yet, but I’d like to make some graphic front ends that make components and I’d like to make software by just connecting them together. Dataflow programming is very declarative. There’s no notion of sequential state. There’s no program counter flipping through this thing. It just is. It’s a declarative model and it’s very easy to understand. And I miss that in most programming languages.
 What’s going on inside the black boxes can be exceedingly complicated. But gluing things together from these complicated components does not itself have to be complicated. The use of grep is not complicated in the slightest. And what I don’t see in system architectures is this clear distinction Joe Armstrong 215 between the gluing things together and the complexity of the things inside the boxes. When we connect things together through programming language APIs we’re not getting this black box abstraction. We’re putting them in the same memory space. If grep is a module that exposes routines in its API and you give it a char* pointer to this and you’ve got to malloc that and did you deep copy this string—can I create a parallel process that’s doing this? Then it becomes appallingly complicated to understand. I don’t understand why people connect things together in such cconnect things together in simple ways.
 And another thing, very important for problem solving, is asking my colleagues, “How would you solve this?” It happens so many times that you go to them and you say, “I’ve been wondering about whether I should do it this way or that way. I’ve got to choose between A and B,” and you describe A and B to them and then halfway through that you go, “Yeah, B. Thank you, thank you very much.” You need this intelligent white board—if you just did it yourself on a white board there’s no feedback. But a human being, you’re explaining to them on the white board the alternative solutions and they join in the conversation and suggest the odd thing.
 I’ve never done the experiment of just speaking out loud to an empty room. Seibel: I heard about a computer science department where in the tutor’s office they had a stuffed animal and the rule was you had to explain your problem to the stuffed animal before you could bother the tutor. “OK, Mr. Bear, here’s the thing I’m working on and here’s my approach—aha! There it is.”
 Michelangelo is doing the roof of the Sistine Chapel or something and he’s got a whole team of painters helping him. So he would sketch the big picture first. These huge areas have got to be done in blue and green. So that’s rather like writing a program. The first sketch is this broad sketch where everything’s in the right place. Some of these places are going to be filled with uniform color and just can be filled in fairly rapidly—you don’t have to think. And then you get to the details of the eyes—that’s tricky stuff. You know you can do it. And the eye is in the right place because the picture is OK. So you go and do the eye and the detail. That’s not to say that’s easy—that’s the difficult bit, actually. You’ve got to really concentrate while you’re doing the eye. You don’t have to really concentrate while you’re doing the forehead or the cheeks because they’re fairly uniform. A bit of stubble here so you pay a sort of half concentration.
 I like to figure out how things work. And a good test of that is to implement it yourself. To me programming isn’t about typing code into a machine. Programming is about understanding. I like understanding things. So why would I implement a JPEG thing like we talked about earlier? It’s because I’d like to understand wavelet transforms. So the programming is a vehicle to understand wavelet transformations. Or why do I try to do an interface to X Windows? Because I wanted to understand how the X protocol worked.
 Joe’s Law of Debugging, which is that all errors will be plus/minus three statements of the place you last changed the program.
 And in a way, writing the documentation is thinking about the types in a way. I suppose you start off with “is a”. You say, “A melody is a sequence of notes.” Right. OK. A melody is a sequence of chords where each chord is a parallel composition of notes of the same duration. Just by defining terms in your documentation—a something is a something—you’re doing a sort of type analysis and you’re thinking declaratively about what the data structures are.
 He says things like, “Do good stuff.” He says, “If you don’t do good stuff, in good areas, it doesn’t matter what you do.” And Hamming said, “I always spend a day a week learning new stuff. That means I spend 20 percent more of my time than my colleagues learning new stuff. Now 20 percent at compound interest means that after four and a half years I will know twice as much as them. And because of compound interest, this 20 percent extra, one day a week, after five years I will know three times as much,” or whatever the figures are. And I think that’s very true. Because I do research I don’t spend 20 percent of my time thinking about new stuff, I spend 40 percent of my time thinking about new stuff. And I’ve done it for 30 years. So I’ve noticed that I know a lot of stuff. When I get pulled in as a troubleshooter, boom, do it that way, do it that way. You were asking earlier what should one do to become a better programmer? Spend 20 percent of your time learning stuff—because it’s compounded. Read Hamming’s paper. It’s good. Very good.
 After college I worked for two years, for a software company in Cambridge. And after two years I said, “It took me four years to get sick of school and only two years to get sick of work, maybe I like school twice as much.”
 I guess the biggest change was going from one person to a team and figuring out how those kinds of interactions work. That’s something you don’t normally get in school. I guess some of the schools are starting to bring that into the curriculum more. When I was in school, working as a team was called cheating.
 Seibel: And do you think that changes the kind of people who can be successful at programming now? Norvig: I think the people that are really successful are the same—at least that’s what I see around here. But, yeah, it is a little bit more of, “Can I quickly get an understanding of what I need,” and less of, “I need complete understanding.” I think some of it is bravado, this willingness to say, “I’m just going to go ahead and do it,” the fearlessness of saying, “I don’t understand everything that’s going on, but I went into the documentation and I learned these three things. I tried it and it worked, so I’m just going to go ahead.” That gets you to a certain point, but I think to really be a good programmer, you can’t just do that. You have to understand a little bit more, and say, “Is it safe, what I’m doing here? Or what are the failure cases? Sure, I tried it once and it worked, but is it always going to work? How do I write test cases to show that and to understand it a little better, and then once I’ve done that, can I extract what I’ve done and publish a new tool that other people can use because I’ve put these pieces together in a certain way.”
 At Google, I think it’s easy because we have this “launch early and often” philosophy. And because of the way the company is, for a number of reasons: one, most of our products we don’t charge any money for so it’s easy to say, well, go ahead and ship it; how much could they complain? The other one is we’re not stamping CDs and putting them in a box so if there’s something that’s not complete today or even if it has a bug, it’s not a disaster. Most of the software is on our servers so we can fix it tomorrow and everybody gets the update instantly. We don’t have this nightmare of installing updates. So it makes it easier for us to say, “We’re just going to launch things and get some feedback from the users and fix the stuff that needs to be fixed and don’t worry about the other stuff.”
 It often seems that people who write the worst spaghetti code are the ones who can hold the most in their head—that’s the only way they could possibly write code like that.
 You look at Knuth’s original Literate Programming, and he was really trying to say, “What’s the best order for writing a book,” assuming that someone’s going to read the whole book and he wants it to be in a logical order. People don’t do that anymore. They don’t want to read a book. They want an index so they can say, “What’s the least amount of this book that I have Peter Norvig 318 to read? I just want to find the three paragraphs that I need. Show me that and then I’ll move on.” I think that’s a real change.
 I’d hung around MIT so much and had obtained copies of Lisp documentation from the Artificial Intelligence Lab and I would sneak into the labs and play with the computers. The doors were open in those days—the Vietnam protests had not yet happened, which is what caused them to put locks on the doors.
 In the ninth grade Ralph Wellings, who lent me those books over the Thanksgiving weekend, struck a deal with me. He said, “I notice you’ve been getting 100 percent on all your math quizzes.” He said, “I’ll let you spend four math classes a week in the computer room if on the fifth day you take the quiz and get 100 percent. If you ever get less than 100 percent then the deal is over.” So that was incentive. I proceeded to ace quizzes for the rest of the year—I studied math especially hard and that gave me access to the computer.
 And when I got to Harvard, if I had a spare hour to kill in the morning I would go over to Lamont Library and I would do one of two things: I would read my way backwards through Scientific American and I would read my way forward, from the beginning, in Communications of the ACM. So I was, in particular, trying to pick up all of Martin Gardner’s columns on mathematical games
 It strikes me that one of the problems of a programming language like Pascal was that because it was designed for a one-pass compiler, the order of the routines in the file tended to be bottom-up because you had to define routines before you use them. As a result, the best way to read a Pascal program was actually backwards Guy Steele 336 because that would give you the top-down view of the program. Now that things are more free-form, you really can’t count on anything other than the programmer’s good taste in trying to lay things out in a way that might be helpful to you. On the third hand, now that we’ve got good IDEs that can help you with cross-referencing, maybe the linear order of the program doesn’t matter so much. On the fourth hand, one reason I don’t like IDEs quite so much is that they can make it hard to know when you’ve actually seen everything. Walking around in a graph, it’s hard to know you’ve touched all the parts. Whereas if you’ve got some linear order, it’s guaranteed to take you through everything.
 And while features have been added to the language over the last 12 or 13 years, I think the team that designed Java in the early ’90s thought they were designing a complete language for a specific self- contained purpose. You know, they were aiming at set-top boxes.
 On the other hand, it’s really hard to make a language that’s great at everything, in part just because there are only so many concise notations to go around. There’s this Huffman encoding problem. If you make something concise, something is going to have to be more verbose as a consequence.
 Steele: Well, they feel different in that I’m very aware that the primary reader for English prose has a very different kind of processor than a computer. So I can’t use recursion in quite the same way, for example. For sophisticated readers I can use it a little bit. But there’s a constant awareness of how a reader is going to process the text and understand it. Something I worry about a lot when I write, that I’m less worried about with a computer, is about the ways in which English is ambiguous. I’m constantly worrying about ways in which the reader might misinterpret what I’ve written. So I’ve actually spent a lot of time consciously crafting the mechanics of my prose style to use constructions that are less likely to be misinterpreted.
 o I guess there’s lessons there—the lesson I should have drawn is there may be more than one bug here and I should have looked harder the first time. But another lesson is that if a bug is thought to be rare, then looking at rarely executed paths may be fruitful. And a third thing is, having good documentation about what the algorithm is trying to do, namely a reference back to Knuth, was just great.
 In particular, the details of the programming tend to take a local point of view and the invariants tend to focus on the global point of view. It’s in doing the proof that you cause those two things to interact. You look at how the local steps of the program affect the global invariant you’re trying to maintain
 Seibel: There’s a Dijkstra quote about how you can’t prove by testing that a program is bug-free, you can only prove that you failed to find any bugs with your tests. But it sort of sounds the same way with a proof—you can’t prove a program is bug-free with a proof—you can only prove that, as far as you understand your own proof, it hasn’t turned up any bugs. Steele: That’s true. Which is why there is a subspecialty in the discipline having to do with mechanical proof verification. And the hope is that you then reduce the problem to proving that the proof verifier is correct. Which is—if you can write a small enough verifier—actually a much more tractable problem that verifying the proof of any rather large program.
 If I could change one thing—this is going to sound stupid—but if I could go back in time and change one thing, I might try to interest some early preliterate people in not using their thumbs when they count. It could have been the standard, and it would have made a whole lot of things easier in the modern era. On the other hand, we have learned a lot from the struggle with the incompatibility of base-ten with powers of two.
 Ingalls: Right. And what was notable about these was that until that time profiling had typically been in terms of memory locations, and it took a quantum mechanic to know what the results were telling you, whereas this came out in terms of your source code and you could see, “Oh, it’s spending all its time here.” This was immediately usable to the user. I recognized, “Whoa! people could be using this.”
 Anyway, that sold great. I can remember several sales calls where I’d go out and as a demo I’d run it on one of their programs and, in the course of the demo, would show them how to save more money than the program cost.
[Note] typically you’re working late at night because that’s when it was less expensive. This is probably where the "late-night hacker" thing came from.
 It’s like what math did. Math found by symbolizing things that you could simplify a lot of stuff. Then, because of that, you could start to think about bigger constructs. That’s my hope.
 Though Don Knuth did write TeX in pencil in a notebook for six months before he typed in a line of code and he said he saved time because he didn’t have to bother writing scaffolding to test all the code he was developing because he just wrote the whole thing.
 My one wish for the mainstream, in the context of computer science, is that people would go back to first principles a little bit more about ways to leverage computing in the intellectual space. We’ve gotten incredibly good with the programming systems and the languages we know. What if we were that good with logic programming? And had it integrated well? I think we would be doing extraordinarily more stuff in much more of a human-oriented space. It does go in the direction of artificial intelligence. You have to know that at some point we’re going to cross a threshold where computers will be doing a better job thinking about stuff than we do.
 Seibel: Smalltalk was originally envisioned as a platform for use in education, right? Ingalls: It was envisioned as a language for kids—children of all ages—to use Alan’s original phrase.
 Seibel: Seymour Papert wrote in Mindstorms about debugging as an important element of an intellectual toolkit—the idea that the name of the game is not to get the right answer but to get an answer and then debug it. Ingalls: Oh, absolutely! People should learn to think clearly and to question. And to me it’s very basic. If you grow up in a family where when the cupboard door doesn’t close right, somebody opens it up and looks at the hinge and sees that a screw is loose and therefore it’s hanging this way vs. if they say, “Oh, the door doesn’t work right; call somebody”—there’s a difference there. To me you don’t need any involvement with computers to have that experience of what you see isn’t right, what do you do? Inquire. Look. And then if you see the problem, how do you fix it? To me that’s so basic and human and comes so much from parent to child.
 Seibel: Can you identify any big changes in the way you think about programming now? Ingalls: That’s a good question. One thing is we’ve got lots of computer cycles to spend. So I’m comfortable now, as the pejorative saying goes, pissing away cycles to get something done cleanly.
 Ingalls: I don’t know of anybody who does that if they have the choice of using a good debugger. Because where do you put the print statement? You put it there. Well, wouldn’t you just like to be there, looking at everything, instead of just printing it?
 You know the old story about the telephone and the telephone operators? The story is, sometime fairly early in the adoption of the telephone, when it was clear that use of the telephone was just expanding at an incredible rate, more and more people were having to be hired to work as operators because we didn’t have dial telephones. Someone extrapolated the growth rate and said, “My God. By 20 or 30 years from now, every single person will have to be a telephone operator.” Well, that’s what happened.
 The thing that he said that made a profound effect on me was how important it is to measure things; that there’ll be times—maybe more times than you think—when your beliefs or intuitions just won’t be right, so measure things. Even sometimes measure thingsto measure. That had a profound effect on me.
 I have a little bit of a rant about computer science also. I could make a pretty strong case that the word science should not be applied to computing. I think essentially all of what’s called computer science is some combination of engineering and applied mathematics. I think very little of it is science in terms of the scientific process, where what you’re doing is developing better descriptions of observed phenomena.
 But that brings me to the other half, the other reason why I like Python syntax better, which is that Lisp is lexically pretty monotonous. Seibel: I think Larry Wall described it as a bowl of oatmeal with fingernail clippings in it.
 Seibel: Did you like teaching? Thompson: To an extent. I’ve gone back and taught twice. Taken a year off and taught one year at Berkeley in ’75–‘76 and one year in Sydney in ’88. It’s fun. I really, really enjoy it. I was doing research in the labs and I went to Berkeley to teach and to learn the classes I was teaching from the bottom up since I never had a computer-science education. A normal visiting teacher teaches one class. I taught five classes. Some classes I taught twice and I thought they were the best because the first year I was learning and the second time I taught it I knew where it was going and I could present it organized and be two steps ahead of the students. The third class was just boring. I taught one class three times and it was just wrong. So I could never Ken Thompson 455 be a teacher because you end up teaching your class over and over and over. I could never do that. But I love the teaching: the hard work of a first class, the fun of the second class. Then the misery of the third.
 Seibel: How do you identify talented programmers? Thompson: It’s just enthusiasm. You ask them what’s the most interesting program they worked on. And then you get them to describe it and its algorithms and what’s going on. If they can’t withstand my questioning on their program, then they’re not good. If I can attack them or find problems with their algorithms and their solutions and they can’t defend it, being much more personally involved than I am, then no. At the same time you can get a sense of enthusiasm. It’s not something you ask directly, but in the conversation you’ll come with this enthusiasm-ometer, and that is tremendously helpful for me. That’s how I interview. I’ve been told that it’s devastating to be on the receiving side of that.
 I’m asking them to describe something they’ve done that they’ve spent blood on. I’ve never met anybody who really did spend blood on something who wasn’t eager to describe what they’ve done and how they did it and why. I let them pick the subject. I don’t pick the subject, so I’m the amateur and they’re the professional in this subject. If they can’t stand an amateur asking them questions about their profession, then they don’t belong.
 But it’s worse than that. The operating system is not only given; it’s mandatory. If you interview somebody coming out of computer science right now, they don’t understand the underlying computing at all. It’s really, really scary how abstract they are from what a computer is or even the theory of computing. They just don’t understand it.
 It was a drum machine—the drum was constantly spinning and that’s where your instructions were. So the way one got it to run fast involved spacing the placement of the instructions on the drum so as it turned the next instruction would be in the right place.
 That was the first instance of something I got an undeserved reputation for. I know that my boss, and probably some other of my colleagues, have said I was a great debugger. And that’s partly true. But there’s a fake in there. Really what I was was a very careful programmer with the arrogance to believe that very few computer programs are inherently difficult. I would take some piece of code that didn’t look like it was working and I would try to read it. And if I could understand, then I could usually see what was wrong or poke around with it and fix it. But sometimes I would get a piece of code—often one that other people couldn’t make work—and I would say, “This is way too complicated.” So I would think through what it was supposed to do, throw it away, and write it again from scratch. Some of the folks I worked with—like Will Crowther—who are terrific programmers, couldn’t tolerate that. They would believe that by doing that, I would probably have fixed the 2 bugs that were there and introduced 27 new bugs. But the fact is, I was good at that. So I would rewrite stuff completely and it would be organized differently than the original programmer had organized it because I had thought about the problem differently. Typically, it was simpler than it used to be, or at least simpler to my eyes. And it would work. So I got this reputation—I fixed these mysterious bugs that nobody else could fix. Fortunately, they never asked me what the bug was. Because the Bernie Cosell 526 truth of the matter is if they’d have asked, “How did you fix the bug?” my answer would have been, “I couldn’t understand the code well enough to figure out what it was doing, so I rewrote it.”
 And I believed, as I likely still believe now, that anything I can understand, I can make a computer do.
 I got a little glimmer of fame because Danny Bobrow wrote up “A Turing Test Passed”. That was one of the first times I actually got some notice for my stupid hacking: I had left Doctor up. And one of the execs at BBN came into the PDP-1 computer room and thought that Danny Bobrow was dialed into that and thought he was talking to Danny. For us folk that had played with ELIZA, we all recognized the responses and we didn’t think about how humanlike they were. But for somebody who wasn’t real familiar with ELIZA, it seemed perfectly reasonable. It was obnoxious but he actually thought it was Danny Bobrow. “But tell me more about—” “Earlier, you said you wanted to go to the client’s place.” Things like that almost made sense in context, until eventually he typed something and he forgot to hit the go button, so the program didn’t respond. And he thought that Danny had disconnected. So he called Danny up at home and yelled at him. And Danny has absolutely no idea what was going on. Except Danny knew about my terminal. So he came in and tore the typescript off of the thing, to save it.
 I have a couple of rules that I try to impress on people, usually people fresh out of college, who believe that they understand everything there is to know about programming. The first is the idea that there are very few inherently hard programs. If you’re looking at a piece of code and it looks very hard—if you can’t understand what this thing is supposed to be doing—that’s almost always an indication that it was poorly thought through. At that point you don’t roll up your sleeves and try to fix the code; you take a step back and think it through again. When you’ve thought it through enough, you’ll find out that it’s easy.
 Programmers are the worst optimizers in the world. They always optimize the part of the code that’s most interesting to optimize, and almost never get the part of the code that actually needs optimization. So you get these little nuts of very difficult code that have no point. I always tell the people working with me, “Code it as lucidly, as easy to read, as crystal- clear as you can. Do it the simple way. And then if it needs to be sped up, we’ll deal with that later. If you’ve done it right, we can draw a little box around this piece.” Eons ago one of the versions of Emacs had one page of the source code that was a gigantic skull and crossbones in comments that said something like: “Seriously twisted code follows this thing.” It was some piece of the innermost guts of the search code or something like that that they had optimized the hell out of. That’s a place where I can see that this piece is really tough. So there’s a big black box around it saying, “Don’t stray in here, unless you know what you’re doing.”
 His numerous awards have included the first Association for Computing Machinery Grace Murray Hopper Award (1971), the Turing Award (1974), and the National Medal of Science (1979). In 1990 he stopped using email, explaining that his job was not “to be on top of things” but “to be on the bottom of things” deeply understanding and explaining large areas of computer science so he could explain them in his books.
 Knuth: The first rule of writing is to understand your audience—the better you know your reader the better you can write, of course. The second rule, for technical writing, is say everything twice in complementary ways so that the person who’s reading it has a chance to put the ideas into his or her brain in ways that reinforce each other. So in technical writing usually there’s redundancy. Things are said both formally and informally. Or you give a definition and then you say, “Therefore, such and such is true,” which you can only understand if you’ve understood the definition. Or you’ll say, “We define a equals the such-and-such to be the set of all leading elements.” So this informal term, the set of all leading elements, is complemented by the mathematical description of how we constructed the seta. So literate programming is based on this idea that the best way to communicate is to say things both informally and formally that are related. And it just provides a natural framework for switching between the natural language, English, and the formal language, C or Lisp or whatever is your formal language, and putting this together. So that, to me, has to be a win for documentation.
 I think it’s just my personality that I like to attack things and find errors. My juices are working when I’m playing the game as the opponent rather than if I’m just sitting there trying to say, “Oh, yeah; now why is this working?” Seibel: It’s curious that that’s what gets you going, yet your life’s work is explaining things. Do you think that approach somehow feeds into how you explain things? Knuth: The only thing I can claim for my explanations is that I try to match a natural brain process of seeing things in two different ways at a time in order to understand something better. I think the key is usually to have a stereo view instead of a one-dimensional view. I don’t know how that affects this attacking business. But when you’re attacking—when you’re playing the game, trying to defeat something—it arouses competitive hormones or something that just stimulates the brain in a way that probably just means that I’m trying more than one way to get at it. A good explanation is a similar thing. A good explanation somehow combines different viewpoints.