Too close for comfort, the late miss Patsy and Mouse

It’s pair programming, not pair coding

Jasper Sprengers

--

Summary: pair programming has never been as popular or widespread as other agile practices. The practice of sacrificing up-front design and go straight to code is likely a factor. While I am still not a fan of pair coding, I do believe there’s a lot to be gained from more explicit design in regular group session between the developers in the team.

Pair programming has a long and respectable history. None other than Frederic Brooks of Silver Bullet fame practised it as early as 1953. In terms of seniority it makes Scrum, CI/CD and BDD look like recent fads by comparison. But where many teams practise the latter with varying degrees of commitment and consequent success, pair programming has never been popular in any team that I ever worked in.

From personal experience I am not surprised. I must have racked up no more than a week of solid pairing during 22 years as a developer, which was more than enough to my taste. What’s more, I wasn’t convinced of the alleged benefits.

There’s a slightly unsavoury intimacy about using the same keyboard, mouse and monitor that doesn’t work for me at all. I don’t like touching other people’s equipment (definitely no pun intended), and I certainly don’t want them manhandling my keyboard or mouse, pointing their finger at and even against my screen — the horror! Covid has at least backed me up on these germaphobe hang-ups, but it’s more than simple hygiene. I am picky about my peripherals. A crappy company-issue USB wired mouse is beneath me. My development environment is set up just the way I like it, with custom key shortcuts that don’t make sense to anyone but me. I like to think I am getting more easy-going since reaching middle age, but I draw the line when it comes to my workstation.

Now these physical barriers needn’t be a deal-breaker in themselves. You can swap keymap configuration in your IDE easily. You can attach two keyboards and mice to the same workstation — for which you’ll need a larger desk, though. You can each stay at your own workstation and use a feature like IntelliJ’s code-with-me plugin. Physical distance doesn’t matter anymore then. Yet no physical aid can make the practice any more appealing to me, and that’s because of the mental challenge that working on the same piece of code together imposes on your brain. The way we tend to code doesn’t scale well to more than a single brain.

Peeling a sack of potatoes is perfectly scalable as long as everyone has their own knife

The school of pair programming tells you to switch roles between writing the code (the driver) and observing/reflecting on what’s being written (the navigator). Why do they insist on that division? It’s not because using the same mouse and keyboard at the same time is cumbersome: there are ways around that. No, the reason we need to take turns in these distinct roles is because of the mental processes involved in writing code.

You can’t coordinate two brains on producing a single line of code. Peeling a sack of potatoes is perfectly scalable as long as everyone has their own knife. Coding is nothing like that. It is a thought process that has to manifest itself through a clumsy ancient QWERTY keyboard layout until Elon comes up with a brain implant. The typing itself is an overrated skill. When I told my neighbour in Rotterdam that I briefly worked as a translator he replied: Isn’t that just re-typing something in a different language? I didn’t argue with him, us being next-door neighbours.

Coding all over the place

Any code I type starts as an extremely ‘drafty’ version. I arrange and re-arrange my thoughts through the code on my screen. Modern IDEs and strongly typed languages make it so easy. You can’t expect me to have a complete mental image of the program in my head that my fingers instantly turn into a bug-free executable. There is nothing linear about the process, in fact I’m all over the place. I type something and throw it out a minute later when a better alternative pops into my head. I can’t mull these alternatives over in my head and then write down the perfect code. I need the keyboard for that and I don’t want anyone looking over my shoulder. I certainly don’t want to explain myself verbally each step of the way when I tend to change course a minute later.

This can’t be much fun for the other party either. They have to sit in forced silence watching me the driver spouting ideas and scrapping them until it reaches a state that I feel I can invite their opinion about.

It doesn’t have to be like this. It is called pair programming after all, not pair coding. The two are not the same thing and many others have made a similar comment in the context of pair programming. Coding is a stage within the much broader discipline of programming, let alone the entire software development lifecycle. Yet we tend to equate the two as if writing the code is all that it’s about.

I really don’t understand why the development community at large has become so dismissive, even scornful, of up-front design. We take a business requirement and jump straight to code, working towards an acceptable version in increments and hoping an elegant design emerges as we code. Even when is works, coding like this is doomed to stay a solo exercise for all the reasons I just explained. The older proponents of pair programming very likely came to the table better prepared, with more detailed specifications and designs. Their Emacs editor wasn’t loaded with all the refactoring goodies we take for granted. The mental process to arrive at working code must have been much more structured and therefore more suitable to do in pairs. That makes all the difference.

Allow me a brief interlude by way of comparison using my hobby of writing drama. A stage play consists of dialogue and stage directions for the actors to interpret and perform, much as lines of code are also interpreted by a virtual machine. Writing the dialogue usually takes up less than half of the entire creative process, although it is 100% of the finished product. A dramatist has to think deeply about plot and characters, make notes and even write biographies of the imaginary people in the play. There is a painstaking iceberg of creativity under the water and you still go through several revisions of the dialogue. You can always make a phrase more poignant, more concise or more informative. The same goes for iterations of writing code. Even with more design up-front your code needs to go through revisions. But the changes will be smaller and less sweeping. There are still many ways to Rome, but the journey will have fewer unexpected detours.

Is it still worthwhile to have two highly paid pair of eyes during the actual coding stage just to avoid implementation errors?

I believe that our habit to design as you go along is the biggest roadblock to successful pair programming. It makes it an unappealing if not impossible option. Yet this straight-to-code approach is a habit you can change. Why not first gather your thoughts in pseudo code and jot down some free-format diagrams? More explicit design becomes crucial when you want to work in pairs. The results will be a better mutual understanding of the task at hand when you start coding.

However, if the two of you have made a good, detailed design of the code-to-be it begs the question whether it is still worthwhile to have two highly paid pair of eyes during the actual coding stage just to avoid implementation errors. I don’t think it’s worth it. In the olden days of waterfall rolling out new versions of code was vastly more expensive compared to a well set-up CD pipeline in a cloud infrastructure. First-time right actually made sense back then.

I can do without pair coding. I am not convinced that the quality gains outweigh the considerable extra cost, and I am quite sure I don’t need it to feel happier in my job. But I would welcome a lot more collaboration in the specification and design stage. There are always requirements to software. The problem is we often don’t make them sufficiently explicit. Likewise, there is always a specification and an architecture, whether or not you put it in writing. Figuring it out from source code is exhausting and painful. Fleshing out the requirements, solving ambiguities, eliminating assumptions: all these had better be addressed before coding.

The good news is that the design stage is much, much better suited to a pair treatment than the coding stage. A group of three or four still works fine. This is the stage to ask questions, find answers and get everyone on the same page. This is where you discuss and define your APIs and data/transfer models, because they are more design than implementation. This is where you write your Given/When/Then scenarios in plain English for behaviour driven design. The group setting is where you address anything controversial and reach consensus on the direction to take.

Design and review together, code on your own

Implementing a better thought-out design into working code will be quicker and less contentious. You have a more detailed grasp of the requirement. Any serious differences of opinion about implementation must be resolved beforehand. After designing together, the pair or trio parts ways to write the code on their own. Later they review each other’s work thoroughly, a practice that many teams already find valuable. An added benefit here is that the reviewer will have been involved in the design of the code, which guarantees better understanding, fewer surprises and higher quality of this vital review stage.

I must press one important parting thought. The approach I outlined is not a return to comprehensive up-front design. Design should be detailed, but focused and iterative. Each design session is concerned with a manageable chunk of work representing no more than a single developer work day to implement. In practice that means getting together every day for an hour to 90 minutes and basically create software without writing the code yet. It works. I have done it. Another warning: please don’t treat it as another meeting that interferes with work. This is work and can be fun too.

--

--

Jasper Sprengers

Writing about anything that delights and/or annoys me about the craft of software making.