Seibeclass="underline" Have you ever pair programmed—sat down at a computer and produced code with another person?
Armstrong: Yeah. With Robert, Robert Virding. We would tend to do that when both of us were kind of struggling in the dark. We didn’t really know what we were doing. So if you don’t know what you’re doing then I think it can be very helpful with someone who also doesn’t know what they’re doing. If you have one programmer who’s better than the other one, then there’s probably benefit for the weaker programmer or the less experienced programmer to observe the other one. They’re going to learn something from that. But if the gap’s too great then they won’t learn, they’ll just sit there feeling stupid. When I have done pair programming with programmers about the same ability as me but neither of us knew what we were doing, then it’s been quite fun.
Then there are what I might call special problems. I wouldn’t attempt them if I’ve got a cold or I’m not on good physical form. I know it’s going to take three days to write and I’ll plan a day and not read email and start and it’s gonna be four hours solid. I’ll do it at home so I know I won’t be interrupted. I just want to do it and get into this complete concentrated state where I can do it. I don’t think pair programming would help there. It would be very disruptive.
Seibeclass="underline" What’s an example of that kind of problem?
Armstrong: Figuring out bits of a garbage collector—it’s the imperative coding—where you’ve got to remember to mark all those registers. Or doing some lambda lifting in the compiler, which is pretty tough—you relabel all the variables and then you’ve got four or five layers of abstract data types all messing around and frames with different stuff in them and you think, “I’ve got to really understand this, really think deeply about it.” You want to concentrate.
I vary the tasks I do according to mood. Sometimes I’m very uninspired so I think to myself, “Ah, who shall I go and disturb now.” Or I’ll read some emails. Other times I feel, right now I’m going to do some hard coding because I’m in the mood for it. You’ve got to be sort of right to do the coding. So how’s that going to work with two people? One of them is just not in a concentrating mode and wants to read his emails and things.
Seibeclass="underline" You did do a kind of serial pair programming with Robert Virding, when you passed the code back and forth rewriting it each time.
Armstrong: Yeah. One at a time. I would work on the program, typically two or three weeks, and then I’d say, “Well, I’ve had enough, here you are, Robert.” And he’d take it. Every time we did this, it would come back sort of unrecognizable. He would make a large number of changes and it’d come back to me and I’d make a large number of changes.
Seibeclass="underline" And they were productive changes?
Armstrong: Oh, absolutely. I was delighted if he found better ways of doing things. We both got on very well. He used to generalize. I remember once I found a variable—I followed it round and round through about 45 routines and then, out it came, at the end, never even used. He just passed this variable in and out of 45 different functions. I said, “What’s that for? You don’t use it.” He said, “I know. Reserved for future expansion.” So I removed that.
I would write a specific algorithm removing all things that were not necessary for this program. Whenever I got the program, it became shorter as it became more specific. And whenever Robert took my program it became longer, adding generality. I believe this Unix philosophy—a program should do what it’s supposed to do and nothing else. And Robert’s philosophy is it should be a general program and then the program itself should be a specific case of the general program. So he would add generality and then specialize it.
Seibeclass="underline" That seems like a pretty deep philosophical divide. Was there any benefit to having the program go through those two extremes?
Armstrong: Oh yes. Every cycle it improved. I think it was a lot better because of that. And probably better than either of us could have done on our own.
Seibeclass="underline" Can you talk about how you design software? Maybe take example of something like OTP.
Armstrong: OTP was designed by me and Martin Björklund and Magnus Fröberg. There were just the three of us did the original design. We met every morning at coffee and had a long conversation—about an hour to two hours—and we covered the white board in stuff. I’d take loads of notes—I wrote all the documentation immediately and they wrote all the code. Sometimes I’d write a bit of code as well. And when I was writing the documentation I’d discover, I can’t describe this, we have to change it. Or they would run into me and say, “Nah, it doesn’t work; this idea we had this morning, because of this, this, this, and this it doesn’t work.” At the end of the day we either got to the point where we got all the documentation and all the code or enough of the code and enough of the documentation that we knew it was going to work. And then we called it a day.
Some days it didn’t work so we said, “OK, we’ll do it again tomorrow.” There wasn’t enough time to do a second pass in a day. But about one pass in a day worked fine. Because it gives us about two hours to discuss it in the morning, about two hours to write the documentation or code it up. And if you spent four hours really thinking hard, that’s a good day’s work. So that worked very, very well. I don’t know how long we worked like that for. Ten weeks, twelve weeks, something like that. And then we got the basic framework and then we had more people. We’d specified the architecture—now we could start growing it. We’d get three or four more programmers in.
Seibeclass="underline" And then how did you divvy up the work for those new folks?
Armstrong: Well, we knew what were prototypes and what were final versions. I’ve always taken the view of system design, you solve the hard problems first. Identify the hard problems and then solve them. And then the easy problems, you know they’ll just come out in the wash. So there’s a bit of experience there in classifying them as easy and hard. I know IP failover or something like that is going to be fairly hard. But I know that parsing a configuration file is going to be easy. In the prototype you might just have a configuration file that you read. You don’t syntax check it—you don’t have a grammar. In the production version you might do it in XML and have a complete grammar and validate it. But you know that that’s a mechanical step to do that. It will take a competent programmer several weeks, or whatever time it takes. But it’s doable, it’s predictable in time, and there shouldn’t be any nasty surprises on the way. But getting the communication protocols right, and getting them working properly when things fail, that I would do in a small group.
Seibeclass="underline" So in this case you wrote the documentation before, or at least while, the code was being written. Is that how you usually do it?
Armstrong: It depends on the difficulty of the problem. I think with very difficult problems I quite often start right by writing the documentation. The more difficult it is, the more likely I am to document it first.
I like documentation. I don’t think a program is finished until you’ve written some reasonable documentation. And I quite like a specification. I think it’s unprofessional these people who say, “What does it do? Read the code.” The code shows me what it does. It doesn’t show me what it’s supposed to do. I think the code is the answer to a problem. If you don’t have the spec or you don’t have any documentation, you have to guess what the problem is from the answer. You might guess wrong. I want to be told what the problem is.
Seibeclass="underline" Is the documentation you write at this stage internal documentation that another programmer would read or documentation for the user?