Daniel Irvine

Code is better when we write it together

28 November 2016

In my last post I discussed the effectiveness of code reviews. Or rather, how they can often be ineffective.

I proposed pair programming as a solution to the issues of code reviews. In fact, working in pairs can remove the need to have any code reviews at all. Working with others is one of the most effective mechanisms we have for building software, and in this post I’ll look into why that is.

The following applies as much to mob programming as it does to pair programming, but for simplicity I’ll only talk about pairing.

Why pairing works

The traditional code review process involves two roles: the author and the reviewer. Pair programming merges the work of the author and reviewer into one task. What was a low-bandwidth, disjointed conversation provided by code-review tools now becomes a high-bandwidth, real-time conversation.

That allows errors to be fixed as soon as they happen, which can be a real time-saver.

Each class, each method, each line of code is a little problem to be solved. As we code, we make ‘micro-decisions’ every step of the way. At each point there’s potential to make a mistake. Some of those mistakes will be simple syntax errors that our compiler or tests will pick up. But others will not be so obvious: design flaws, incorrect assumptions, misunderstood requirements, or perhaps poor data structure choices. When we code solo, these errors can go unnoticed. Then we start building upon them. By the time we’re finished, the entire set of changes may be wrong. After review there will be a lot of rework—assuming the reviewer spots the problem.

But with another programmer watching us, the initial mistake that led to this is spotted early. “Hold on! I don’t think that’s quite right…” they say. We discuss the problem, and then correct it. We are quickly back on the right track.

Pairs go faster

Although it might seem reasonable to think that pairing reduces the productivity of those programmers by a factor of two, the reasoning above shows why pairing can actually be faster than a standard solo development practice. But that’s just one reason. Let’s look at another.

Solo programmers get stuck

When we work alone we often get stuck. There’s something about problem solving which can be quite tricky. We think too fast and get muddled easily, especially when we’re tired or agitated. The longer we’re stuck, the more impossible the problem seems.

If you’re stuck on something, explaining the problem to someone else can suddenly make the solution become obvious. This works because when we explain our thinking to an uninitiated party, we are forced to break the problem down into details, and to slow down our communication enough so that we’re sure they’re following along. Sometimes when we do this we find that we miraculously solve the problem in our heads when we’re still busy describing it! I am sure many of you have experienced this. And the curious thing is that we don’t even need to be speaking to another person for this trick to work; any object with a face is probably good enough. This trick is called rubber ducking and many programmers will be familiar with it.

The beauty of pairing and mobbing is that you are always explaining the problem to somebody else. You work outside of your brain, which loves to rush and get ahead of itself. Pairing doesn’t give your mind a chance to get muddled.

None of this is obvious. If it was, then everybody would have been pairing a long time ago.

Why is pairing resisted?

Many programmers build up a resistance to pairing. The mere mention of it triggers an instant defensive reaction. Given the clear benefits of pairing, why are some people so fearful of it?

Pairing involves unremitting inspection and critique. This is a serious shock to the system, if you’re not used to it. The adrenaline kicks in straight way, putting us on high alert. This zaps us of energy. For beginners, pair programming is exhausting. It’s no surprise that many people feel defeated after their first day of pairing.

And that’s just the first person you pair with. What happens when you pair with the next person? Have you ever heard someone say that they can only pair with certain people? There are as many programming styles as there are programmers. When we’ve been coding solo all our lives, we’re really only used to our own code. The ability to adjust to another person’s style takes time and experience. The ability to adjust to many different styles takes even more.

Effective pairing

Everybody suffers this initial reaction. The solution is simply to persevere. The more we try, the easier it gets.

Each day becomes less and less tiring, until we are able to pair every single day. Eventually, once you’ve paired with enough people and over a long enough time, you realise that you could pair with anyone, anytime, on anything.

And we eventually reach a point where pairing is more productive than solo development.

This isn’t to say that pair programming is never frustrating. We all have bad days. But those days should eventually become few and far between.

Can pair programming replace code reviews?

For small, independent teams, the answer is almost certainly yes. For larger teams, particularly in the enterprise, the answer may be less obvious.

In contrast to code review tools, pair programming forms a natural barrier around the team that keeps code discussion free of outside influence. Technical discussions no longer happen online; they happen in a closed space. Teams increase their autonomy to make their own technical decisions. Any outsiders—perhaps programmers from other teams, or high-level architects—will not be able to hinder the team’s progress.

If there are outside stakeholders who are interested in seeing changes—perhaps, for example, to ensure that code adheres to organisational guidelines—then code reviews are still useful, but take lower priority than before. For example, as a pair you might create a pull request for the code you’ve authored, but then immediately merge it yourselves. That way the pull request is still there for others to observe, but development is not held up waiting for it to be merged.

There’s a lot more to say about pair programming

In this post I’ve touched on some of the benefits of pair programming when contrasted with code reviews. There are other benefits—for example, pair programming is a great way to break down silos. There are also disadvantages to pairing. There’s a lot to say about mob programming. And, of course, there are dozens of strategies and tricks to pairing that are worth knowing. I’d encourage you to continue learning about pairing by sharing knowledge with others and, of course, through deliberate practice.