Saturday, January 27, 2007

Pair Programming is Bad and You Should Never Do It

In a review of the book Dreaming In Code, Joel Spolsky recently remarked in his blog:

"I can’t tell you how many times I’ve been in a meeting with even one or two other programmers, trying to figure out how something should work, and we’re just not getting anywhere. So I go off in my office and take out a piece of paper and figure it out. The very act of interacting with a second person was keeping me from concentrating enough to design the dang feature."

Finally someone has hit the nail on the head about what has been bothering me about pair programming. Here is what I think about it:

If a problem is so trivial that two people sitting in front of a computer chattering away at each other can solve it, then it should be the part of the project that is outsourced, preferably offshore where the cost of doing trivial work is lower.

For sure I have done pair debugging, sometimes even trio debugging when it's an especially thorny problem involving multiple functional units, race conditions, and hardware. And, yes, I have done pair programming when trying to do maintenance on some code in a language I don't know (typically some form of assembly), on a processor I've never used before (typically a DSP), where the original developers left the company years ago, and a vice president is calling every half hour to helpfully ask how that escalated field problem is coming along. And sometimes getting a bunch of folks in the same room in front of a whiteboard is a very good thing indeed, particularly in those cases where the Engineering staff is pretty much convinced that what Marketing has promised is pretty much impossible (although to be fair, it never was).

So I understand there are circumstances where working closely in pairs or even in larger groups is not only a good idea, it is downright mandatory (and sometimes it can even be fun). But the way pair programming is usually described sounds more distracting than anything else. When having to interact with another person while trying to figure out something difficult, my interior monologue runs to "STFU!"

Having said that, I am very much in favor of 100% coverage by code inspections. The thought that I might be the only engineer to see my code terrifies me, and I consider myself a pretty good developer, with a long track record of successful product development. But I'm far from perfect. I would not have thought this to be controversial, but apparently it is, if my own recent personal experience is any indication. But I have never been in a code inspection in which I didn't learn something useful. Sometimes it's "Hey, that's a great idea, I'm going to steal that!" Or "Oh boy, I'm going to make sure I never make this mistake." Or maybe "Man, what was I thinking?"

What I am not sure of is when to do the code inspection. In his seminar "How to develop better firmware faster", Jack Ganssle cites studies that indicate the sooner the better. Like, right after you have written the code and before you've even compiled it. This is an economic argument: inspections are a more effective use of engineers' time than debugging, presumably because an inspection that eliminates a bug on average takes less total engineer-time than debugging to remove the bug.

This was likely true back when we had long modify-compile-test cycles, particularly in the dark ages when such cycles involved keypunches and computer operators. But with modern tool chains and disciplines like test driven development (TDD), I'm not convinced. When I'm inspecting code, I like to be able to make basic assumptions, like [1] it compiles, and [2] at least the constructors and getters work. Otherwise I'm too paranoid and spend way too much bandwidth looking at the nesting of parentheses instead of concentrating on the overall design intent.

Since I mentioned TDD, I'd better plug that too. Like a lot of old guys, I stumbled into TDD myself before I ever heard the term "unit test", just because I have the virtue of all good developers: I'm lazy. I stumbled into structured programming, and later into object oriented design, the same way. Not the easy way, of course, by learning about it from a class or a book. But by doing software development the hard way and finding I was spending so much time at work that I wasn't keeping up with Battlestar Galactica. (That would be the original BSG.) The good part about this was when I was finally introduced to these concepts, there was zero resistance on my part. It was more like I took serious offense that no one had explained this to me earlier, saving me a lot of time and effort.

So if there's anything you know that will help me keep up with the new BSG, why don't you just let me know now, instead of forcing me to painfully learn it myself? I appreciate it.


mcjoe said...

I'm not sure that the issue is as white and balck as Joel would have us believe. In a group of talented, motiviated developers, I seldom find myself distracted away from the problem. More often than not, we iterate to a solution very quickly. I'm not sure that every problem solved with pair programming fits into the "its trivial, so offshore it" category.

As a side note, Joel is also big on a very quiet work area, which may have something to do with his opinion of PP.

I haven't actually spent any time doing formal pair programming, but on one project, we did do a lot of what I will term collaborative programming. When a developer felt that a piece of code needed another pair of eyes, he or she called another developer over to discuss the code. This worked very well.

I recently interviewed an applicant who claimed that pair programming worked very well when writing unit testing. I am intrigued by this concept and plan to give it a try. The idea is that if you get a pair of developers to agree on what needs to be tested, and they implement these tests, then the quality of the code will be improved by the improved testing performed. I will be blogging about how this works when we begin to implement it.

I agree that pair programming isn't the panacea for all programming problems, but I'm not ready to completely write it off either.

Chip Overclock said...

It occurs to me that this is one of the problems I have with all trendy software development processes (or trendy business processes): the idea that one size fits all. But anyway...

I am very intrigued by some of the stuff I've read about development teams working on mission critical or extremely secure applications, where the team is split into the home team and the aggressor team, the latter writing unit tests to try to break the code. (This is in addition to having a seperate QA organization that does functional testing against requirements.)

I look forward to reading your article when you blog about this. (For other readers, there is a link to Joe's blog from my blog.)

Demian L. Neidetcher said...

Chip, I think you're just as wrong as dogmatic XP evangelists. XP has some lessons for us but you gotta use your head and apply it where you think it makes sense.

In a team that communicates well, without any heroes I think paired programming can be used judiciously to get through tough parts of the architecture.

Maybe it's figuring out a tough algorithm or defining an interface but sometimes it's just good to get another set of eyes on a problem. Granted, sometimes it's better to just go off and do it, then present your results to others.

To put some numbers to it, I probably am involved in paired programming 5% of the time and that seems about righ to me. Paired programming is un-American. We're cowboys, individuals, just not wired to work like that. But sometimes it just makes sense.

Chip Overclock said...

Well, of course, you're right. Anyone who says things like "always" and "never" are always wrong, never right.

5% sounds like it's in the ballpark, given my personal experience. Like I mentioned in my article, I've used pair programming when appropriate, and was relieved to do so. But using it as a rule, as a mandatory part of your development process, isn't a good plan. (But I still believe in 100% mandatory code inspections.)

jlorenzen said...

In his book, Producing Open Source Software, Karl Fogel, highly suggested performing code reviews by viewing the commit emails. He mentioned that this approach is critical in open source projects.
I kind of see code reviews practiced this way as a sort of pair programming.

Chip Overclock said...

I worked on a project for a couple of years that used this approach: the "diff listings" were emailed to the team. I agree that this approach can work well. However, some developers (like me) have a natural tendency towards introversion (not you of course), or when things get really busy just don't have time to devote to reading the diff carefully. This is for sure a judgement call, but it is where a formal inspection meeting, as painful as that may be, can really pay off. It forces folks to take the time to really discuss the code. Depends of course on the scope of the project, and, I find, whether you are writing new code (in which case everyone may have a pretty good grasp of what is going into the base) or modifying a large legacy code base (in which the subject matter experts for the modules being changed may not even be on the project). I think my big picture view is "it depends", which is why I am generally against any one-size-fits-all processes. However, this is not what most managers, who strongly desire a mechanized process that is guaranteed to succeed, want to hear.

As always, thanks for the comments! I learn the most from those that disagree with me, so feel free to do so!

Android app developer said...

This is one of the impressive post.
I like your blog creativity.This is one of the Important post.