Seibel: And do you remember any particular aha! moments where you noticed the difference between working on something by yourself and working on a team?
Norvig: I don’t know if it was so much moments, but just this realization that you can’t do everything yourself. I think a lot of programming is being able to keep as much as you can inside your head, but that only goes so far, at least in my head. Then you have to rely on other people to have the right abstractions so that you can use what they have. I started thinking about it in terms of, “How is this likely done?” rather than, “I know how this was done because I did it.” If I were to have done this, how would I have done it? I hope that it’s like that, and if it’s not, figure out why not, and then figure out how to use it.
Seibel: Do you think that learning to work on teams that way also enables you to actually work on bigger things even by yourself when you’re sort of a team spread across time?
Norvig: I think that’s true and that’s certainly something I see in the younger programmers that are coming out now. Another difference between now and then is it seems like it’s much more assembling pieces now rather than writing everything from scratch. Now, for a school assignment, someone says, “OK, I needed a website, so I used Ruby on Rails for this, and I used Drupal for that part, and then I had this Python script, and then I downloaded this statistical routine,” and it’s all scripting to put together these pieces rather than writing everything from scratch. So I think understanding interfaces and how they go together is more important than all the details of the insides of these packages.
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.”
Seibel: How did you like to work on a team when you were a programmer? Is it better to take the problem and split it up so everybody gets their piece? Or do you like the XP model of pair-program everything and everybody owns all the code collectively?
Norvig: I guess it’s more break it up. Steve Yegge’s got this “Good Agile, Bad Agile” piece. I think he’s about right. Ten percent of the time it is a really good idea to sit down together because you want that shared understanding. I think most of the time you’re not going to be as effective.
If you have two good programmers, it’s better for them to work independently and then debug each other’s work afterwards rather than to say, “We’ll take a 50 percent hit just for that added set of eyes.”
I think it is important to get together when you’re figuring out what it is you want to do both in terms of brainstorming what is the problem we’re trying to solve and what is the functionality going to be here? You don’t even know what the product is before you start. That you really want to do together. Then you get to the point of saying, “OK, now we know what we want to do. How are we going to divide it up?” That you want to do together. Once you have a pretty good idea, I think you’re better off spending most of the time on your own. You want feedback, so I think you should require every piece of code to be reviewed by another set of eyes, but it doesn’t have to be real-time, when you’re writing it.
I remember the IBM master-programmer idea, and that just seemed like the dumbest thing I have ever heard of. Why would anybody want to subject themselves to being a gopher for the one real programmer?
Seibel: I’m surprised you think the master-programmer model is such a dumb idea. In your “Teach Yourself Programming in Ten Years” essay you make the point that programming is a skill that, like many skills, probably takes about a decade to really master. And lots of crafts had master/journeymen/apprentice kind of hierarchies. So maybe nobody wants to be the apprentice, but maybe it isn’t crazy to say that somebody who’s been through that decade-long learning experience should be doing different work than someone who’s fresh out of school.
Norvig: I think the best part of the apprentice approach is that you get to watch the master, and I would like to see more of that. So I guess that’s another use of pair programming. I can see that it’d be really good, if you were inexperienced, to watch somebody who’s much more experienced. Particularly for the types of things that aren’t taught as much, like debugging skills. Anybody can learn algorithms and so on, but they don’t really teach debugging and watching someone, and saying, “Wow, I never thought of doing that,” that’s really useful.
But I think part of the reasons why you had master and apprentice is because the materials were rarer. When you were doing goldsmithing, there’s only so much gold. Or when the surgeon’s operating, there’s only one heart, and so you want the best person on that and you want the other guys just helping. With coding, it’s not like that. You’ve got plenty of terminals. You’ve got plenty of keyboards. You don’t have to ration it.
Seibel: Speaking of things that aren’t taught as much, you’ve been both an academic and in industry; do you feel like academic computer science and industrial programming meet in the right place?
Norvig: It’s a big question. I don’t think there’s a lot of waste in computer science curriculum. I think that it’s mostly very good stuff to know. I think going to school is useful, but it’s not everything that you need to be successful in the industry or to build systems. I do think that curriculum in many schools has been slow to adapt. There are a number of places where that comes into play: working in a team is not taught so much in school. This idea of being able to put the pieces together is not really taught there, but somehow the kids pick it up anyway, so maybe that’s OK. At Google we’re certainly interested in this large-scale cloud computing, parallel computing, and so forth. That’s not taught so much, although I think there’s a lot of interest in it. So I think they lag behind a little bit, but I think it’s still useful.
Seibel: And are there any areas where academics are out in front of industry? Where industry is ignoring good stuff about how we ought to build software.
Norvig: I think to some degree. Probably the best example was the model checking where Intel wasn’t really paying much attention and then they had this big recall and they lost a lot of money because they had a bug in their multiply. And then they started to pay attention, and they went to an academic and said, “What can you do to help us?” So there actually was something there. And now it’s an integral part of what they do, so that was a good example. It seems like programming languages, probably not so much. There’s a lot of work going on but you don’t see a big impact of the newer programming languages. Operating systems, a little bit. We’re supporting this RAD Lab at Berkeley with Dave Patterson and so on. They have some good ideas—how to make reliable systems. But it’s certainly the case that industry has the larger, bigger problems. They may not have all the answers to them—but they’re hitting them harder than in the university setting.