An introduction to pair programming.
2020-07-08
In this blog post, I will cover the history of pair programming, the basics of different pair programming styles, and methods for pair programming effectively. I believe that pair programming is valuable under the right circumstances. This blog post is intended to get you started with pair programming, not to debate its usefulness.
Six women were the original programmers of the ENIAC, the first general-purpose digital computer. Two of them, Jean Jennings and Betty Snyder, worked together to develop a ballistics trajectory program. Just like in far too many stories of women pioneers, other people stole the credit and they weren't invited to the formal ceremony or celebratory dinner.
Although Betty and Jean didn't formally invent the term "pair programming", they developed their software collaboratively and believed in the advantages of doing so.
Betty Snyder and I, from the beginning, were a pair. And I believe that the best programs and designs are done by pairs, because you can criticise each other, and find each other's errors, and use the best ideas.
— Jean Jennings
Both Betty and Jean went by their middle names and changed their surnames in marriage. I used both women's preferred names and maiden names for clarity, partially because Jean's first name was also Betty.
Extreme Programming is a software development methodology created by Kent Beck and introduced in his 1999 book with the same name. It's an Agile approach to software development that takes best practices to the "extreme". For example, XP considers pair programming to be code reviews taken to the extreme. This is because in pair programming, code is reviewed continually. Kent's methodology led to the popularisation of pair programming in the late 90s and early 2000s.
Today, pair programming is also popular at non-XP and even non-Agile workplaces, plus outside of the workplace.
I often pair with friends to teach and learn new things or to collaborate on side projects.
You can share authorship for Git commits with the Co-authored-by
trailer in commit messages.
Casual use drops the word "program" in "pair program". For example, someone might say: "I'm pairing with Alice soon. Want to pair later?" It's also common to call your pairing partner your "pair", but I'll use "partner" for simplicity.
Each partner is considered either an "expert" or a "novice" for a pairing session. Someone's skill level is determined by their experience related to the task at hand, not their job title. A junior developer can be an "expert" for a problem/domain they're comfortable with, and similarly a senior developer can be a "novice" in some cases.
Naturally, there are three possible skill combinations for pairs: expert-expert, expert-novice, and novice-novice. Typically you want to avoid novice-novice pairs. If one or both partners doesn't know enough to get started, they should take some time to individually research and investigate the tasks before pairing.
In driver-navigator pairing, there are two roles at all times: the driver (tactical) and the navigator (strategic). The driver is focused on implementing the current task and the navigator reviews the driver's code while considering the bigger picture. Both partners must constantly verbally communicate with each other.
In an expert-novice pairing, the novice always drives. Two experts can switch roles on any or all of these events:
Pairing can happen on an ad-hoc or scheduled basis, and with static or dynamic pairings. The more frequently pairing occurs and the more diverse the pairings, the higher the team's "bus factor". This is the minimum number of people who would need to be metaphorically "hit by a bus" before it would cause issues for the team.
Strong-style pairing is a version of driver-navigator pairing that is also known as "backseat navigator" pairing. In this style, the navigator gives tactical instructions in addition to strategic instructions. For example, they might tell the driver to create a new method or write output to a file.
Strong-style pairing is meant as an onboarding or knowledge-transfer method and should only be done with expert-novice pairs. The novice "learns by doing" instead of just reading documentation. In regular pairing this would be controlling, but in strong-style pairing this is the point.
Ping-pong pairing combines the practice of pairing with test-driven development (TDD). TDD is also part of XP and requires writing exhaustive tests before writing code. In this pairing style, one partner "pings" by writing a test that will fail. The other partner "pongs" by writing code that passes the failing test.
After each "pong", the partner who just "pinged" becomes the one who "pongs" and vice versa. This makes it best suited to expert-expert pairs. It's possible to follow the "red-green-refactor" method by collaboratively refactoring the newly-written code after each "pong".
In round-robin pairing, pair programmers frequently swap partners. This style is intended to increase the amount of time in which any pair programmer is in a state of "beginner's mind", as every new partner to a pair is new to that task. It also increases the bus factor of the team more rapidly by increasing the number of people with exposure to each piece of code. Swapping typically happens on a time schedule, commonly every 1.5 hours, even if a task isn't finished.
Let's say that two people named Alice and Bob are pairing together. At the swap time, Bob leaves to pair with someone else and is replaced by Carol, who pairs with Alice until the next swap time. At that point, Alice leaves to pair with someone else and is replaced by David, who pairs with Carol until the next swap time. This pattern continues until the round-robin pairing session ends.
Round-robin pairing is normally called "promiscuous pairing". The primary definition of "promiscuous" is "having or characterized by many transient sexual relationships". I think we should minimise sexual references in the programming community and couldn't find alternative terms, so I came up with "round-robin" myself. I recognise that pretty much everyone is still going to use the term "promiscuous", but change has to start somewhere!
Mob programming is similar to pair programming except with more than two people collaborating at once. Like with round-robin pairing, one of the motivating factors is to increase the team's bus factor more rapidly. I could write an entire article about mob programming and all its styles, so I won't delve into it here. I just want you to know that mob programming is something that exists in case you enjoy pair programming and want to explore mob programming later.
When done right, pairing can have many benefits. Here are the ones I've noticed.
Pairing prevents individual distraction by requiring active ongoing collaboration. Partners help each other stay on track, both in general and for a given task. It's way harder for your mind to wander when you're engaged in a technical conversation.
Working as a pair means that there's an extra person to look over the code and spot errors, inefficiencies, and code smells. This improves the long-term health of the codebase.
When two people pair on a certain piece of code, it means that at least two people understand, have contributed to, and have responsibility for it. This increases maintainability and decreases the consequences of a team member being sick or absent.
Sharing skills and approaches helps to prevent over-specialisation and knowledge silos. I can't count the number of little things I've learned from or taught to my partners just from watching each other code. Additionally, strong-style pairing allows for efficient onboarding of new team members.
Discussing problems out loud forces pairs to reconsider their solutions, potentially leading to improved processes. While talking to a rubber duck is fine, talking to someone who can talk back is even better.
It can be hard to focus on the big picture while implementing the small details and vice versa. Humans just aren't that great at multitasking. While pairing, the navigator can focus on "the forest" at the same time that the driver can focus on "the trees".
Ever get stuck on a problem that throws you off, only to realise the answer was right in front of you? By having two brains working on the same problem, partners can un-stick each other and more quickly resolve difficult problems.
When partners are mostly on different ends of social hierarchies, this can negatively impact pairing. Examples of potential social hierarchies include:
The partner with more social power might be more likely to:
This is often subconscious and doesn't mean the partner is a bad person! Just be aware of potential power imbalances to ensure equal participation. That being said, power imbalances don't always lead to problems, nor are they always the cause of problems.
Pairing can also be difficult because of the amount of emotional effort it takes. The good news is that pairing gets a lot easier if you manage this effort effectively.
Pairing for long periods of time can be draining, especially for introverts. Take short breaks at reasonable increments and celebrate completing tasks. A high-five (even virtual) goes a long way!
Partners might fight for control or simply struggle to communicate. Before pairing, discuss differences in each other's approaches and personalities. After pairing, give and share feedback on each other's communication skills. Try to assume good intentions from your partner and approach interpersonal issues with an open mind.
It can be uncomfortable to openly reveal what you do and don't know. On a personal level, embrace vulnerability and accept that nobody knows everything. On an interpersonal level, foster a respectful environment that encourages learning and accepts ignorance. There's nothing wrong with learning something for the first time!
Be pre-emptive, especially if you have more power in the situation. This means suggesting breaks, requesting feedback from your partner, and keeping your partner's spirits up. It's common for partners to need a break but either not realise it or not want to mention it.
Now we know what pair programming is and how to do it well. But what kind of setup do we need?
Ideally, in-person pairing partners should work next to each other with separate keyboards and mirrored screens. It's nice to have separate screens so that partners aren't crowding each other and can easily see everything. Having separate keyboards is especially important if partners are used to different key layouts and/or keybindings than one another.
You'll want to minimise distractions as much as possible. This means having a clean and clear workspace, and ideally working somewhere quiet where you won't disturb or be disturbed by other people. This also means agreeing on an editor, font size, operating system, and so on that is comfortable for both partners. If partners are sharing a screen and/or keyboard, they should agree on those details too.
Remote pairing is becoming more important as many of us work from home. However, remote pairing doesn't have to be a "plan B". It can give partners more flexibility in their individual setups and enables pairing with geographically distant teammates. There are many different tools to facilitate remote pairing.
Live Share for VS Code is my favourite free tool. It's easy to use and has many features including voice chat and remote terminal sharing. Multiple people can edit code at a time, kind of like Google Docs. You can automatically follow your partner's cursor, making it more like screensharing, to prevent things from getting chaotic.
Screen is my favourite screensharing-based remote pairing tool. Naturally, you aren't tied to a specific editor and can share more than just code. There's also built-in video chat so you don't have to use a separate communication tool or call each other. Switching roles is very easy and the navigator can draw on the screen. Screen is normally paid but it's free for individual use during the COVID-19 pandemic. Tuple is similar but it's more expensive and is only available on macOS.
Some other editor-specific tools are Remote Collab for Sublime and CoVim for Vim. You can share your terminal with tmate, but the cursor is also shared. A popular cross-editor tool is Floobits, but it's paid and I think screensharing tools provide better bang for your buck if both partners are comfortable using the same editor.
If you don't want to pick up or pay for a tool right away, some video calling services have screen/cursor control features. These services aren't optimised for reading and editing code though, so you might have to deal with blurry text and high keyboard and mouse latency.
I hope this blog post helped you learn more about pair programming and how you can make the most out of your pairing sessions. Pair programming is fundamentally about collaboration, so some of these techniques can be adapted to collaborate on design, project management, and more. Happy pairing!