Pair Programming and Happiness

Perhaps there is a way to get it right

TDD tmux pairing

What this post is about

Every time an article about pair programming surfaces in one of the Internet's watering holes, I am surprised by the amount of negativity surrounding the practice.

In this post, I suggest two modifications to "standard" pair programming, which should make it more enjoyable, even for introverts and skilled experts.

People complain

Reading the top top-rated comments in one of many threads on pairing, one sees critical comments like these:

I can’t stand pair programming, and I simply would not work somewhere that required it.

Pair programming (..)? Super not a fan.

I’m personally strongly against it.

While I haven't done a through qualitative study on the sentiments expressed, one of the main arguments against pairing seems to be the fact that programmers don't enjoy being forced to socialize against their will. This forced socialization entails things like:

The other counterargument centers around the difficulties in matching skill and experience levels between the two members of a pair. Here, the following come up:

This skills-based barrier to pleasurable and productive pairing is indeed more serious, but I have seen it overcome with a small shift in attitude and approach.

Below, I'd like to present the paring setup and techniques that I've used (and seen used) in the last few years. I believe that they alleviate some of the misgivings about pair programming mentioned above.

Introverts, separate!

I've done most my professional work remotely. A lot of the code I've (co-)developed was written in a pair-programming+TDD setting, remotely.

How does one effectively pair-program when not at the same desk? I'm not the first person to recommend the classic ssh + tmux solution. I believe this solution is strictly better than pair programming at one desk.

It works like this:

  1. The team sets up a shared development box, accessible by ssh/mosh
  2. A pair of team members logs in, tmux attaches to a shared terminal
  3. They run vim emacs inside
  4. They use a separate app for audio. (Mumble, Skype, Slack calls, etc.)

This solution is so good, that I've even used it while working in the same room as the pairing partner (sans voice app, of course). It provides both parties with a shared locus of attention, while not exposing them to physical discomfort.

While this solution clearly eliminates physical issues around pairing, the problem of a shared programming environment remains. As pair programming requires practitioners to be fluent with the tools they use day-to-day, fundamentally there will always be a need for compromise on this front.

Practically, however, most backend programmers will be familiar with either vim or emacs—a judicious use of toggles for switching between setting groups should sort out personal quirks. (For example: at work we bind <F4> to switch emacs from vanilla behavior to evil-mode. It works well enough.)

Jamming is conversation

The other issue is related to skill levels. Simplifying skill levels to a binary of junior and senior, we get 3 possible pairings: both juniors, both seniors, and junior+senior.

The junior+senior combination seems to be the most highly regarded use case for pair programming, even among the detractors. It makes sense that putting the less experienced in close quarters with a seasoned master should benefit the junior. Even in these cases, I can imagine that some seniors may feel that their time isn't being put to good use, while some juniors might get overwhelmed watching their mentor work with great efficiency. This leads to fatigue and 'just watching' as the other person works—definitely a waste of both the devs' time and the employer's money.

The key to getting the most our of pair programming is to Always Be Coding. The common pairing methodology of driver and navigator switching roles every 30 minutes is tedious and wasteful. I believe that turning the coding session into a jam session is the key to making pairing work.

How to keep both parties engaged and coding? If you're applying TDD, it's easy: just do ping-pong pairing. Developer A writes a test. Developer B writes enough of an implementation to make the test pass, then continues with another test. Developer A picks up, and modifies the implementation to meet the demands.

This kind of call-and-response style of development keeps both parties focused on the code, talking and thinking about the task at hand. While TDD works most of the time, there exist some issues which cannot be simply reduced to a test case. Here, still, the challenge-and-reply approach does wonders for code quality and developer engagement. (For example: one developer might challenge the other by saying: "There is a more efficient algorithm", or "I can break this mechanism like so. How will you fix it?", etc.)

By approaching pair programming as a conversation, we can get more mileage out of any combination of skill levels. For two juniors, the back and forth may touch on unit test design or knowledge of the system. Two seniors pairing will get opportunities to critically examine and revise system architecture or coding standards, but the possibilities for jamming are endless. They may even involve betting money (sic!).

Wrapping up

Above, I described two tweaks to pair programming practice that, in my experience, make it much more enjoyable. To summarize:

This concludes my humble contribution to the ongoing conversation around pair programming.

(Edited on 2018-01-30 for spelling)