Pair Programming: A (Semi-) Definitive Guide
“I’m going to need a change of clothes”. Mercifully, it was just profusive sweat, but there was a nagging doubt that a more serious, anxiety-induced bodily malfunction might occur.
The monitors glared at me, and the keyboards, sitting neatly side-by-side, taunted me. To my adrenaline-addled brain, I was just seconds from being marched out the door because of my mental ineptitude and complete inability to program. Nothing prepared me for the look on my partner’s face as he sat down: excited but calm. I wanted to throw up.
That was 14th April 2008, my first ever experience of pair programming, and not coincidentally, my first day at New Bamboo (now part of thoughtbot).
Since that day, almost 7 years ago, I’ve spent a lot of time pair programming and I’ve come, dare I say, to love it. Yes it can be intense and sometimes emotional but, done right, it can also be deeply rewarding.
If you’re used to coding on your own, having two people both staring at the same code may seem wasteful. Healthy skepticism is encouraged — I recommend it most of the time. However, when learning a new skill (of which, pair programming is one), I find it best to suspend judgement and allow yourself time to just play and experience. Once you’ve had an unbiased experience, let your analytic, critical mind kick back in and assess the value.
With that in mind, I’d like to share some lessons I’ve learned the hard way. Hopefully there will be something for everyone: pair programming novices and old-hands alike.
The Basics
Remember your roles. Every pair has to find their own way of working together, but conventionally, one person types and attempts to implement the current feature (the driver), and the other thinks more strategically about the overall direction (the navigator). Switch roles frequently, at least every every 30–40 mins.
Be a good navigator. As the navigator, it’s your job to spot possible problems the driver hasn’t considered: Are any tests missing? Is there pre-existing code that does this? Do you have a simpler approach? You are also the guardian of quality. It takes courage to be strong and gently insist on quality when your pair, in a moment of weakness, wants to skip that test, or cut that corner.
Be fully engaged. Pairing is not easy: it takes effort and discipline. Both partners have a responsibility to commit fully to producing quality code. That means not slacking off and checking twitter or email, or browsing on your phone. Stay focused on the problem in hand.
Minimise unhelpful interruptions. Every interruption breaks your flow, and it takes time to recover. Turn off, move, burn or otherwise destroy anything that will take you out of this flow (email, alerts, flashing lights, sounds). If you worry about missing important messages, set a single, physical reminder (e.g. an egg timer) to stop to check them. Not all interruptions are bad, though — see Local vs Global speed below.
Agree on Coding Standards. Consistent styling makes it easy for anyone on the team easily dive in and work on any code. Don’t waste time and energy arguing over where to put curly braces. Agree on an explicit style guide that enshrines style and formatting decisions (e.g. ruby style guide), then get back to solving the problems that matter. Even better, hook-up automated style-checkers to your project (Hound CI by thoughtbot, Rubocop et al.)
Don’t rush. Think you need to be a rockstar developer, tapping maniacally at the keyboard in a cloud of dust, cranking out solutions in seconds? Most of us mere mortals would produce a pile of gibberish if we worked like that. Programming is not about how fast you can type, it’s about thinking through complex problems. Better to go slowly and do the right things, than rush ahead doing the wrong things. Practice makes permanent so cultivate good habits, and trust that speed will naturally come over time.
Think out loud. What idea are you considering? Why will one approach work better than another? Verbalising your thoughts not only lets your pair know what’s going on in your mind and gives them an opportunity to assist, but it actually helps you solve your own problems too (see Rubber Duck Debugging.)
Take regular breaks. Pairing is intense: exhilarating, but draining too. If you notice your energy flagging, suggest a break. You can stop for the latest hipster, artisanal coffee, a chat with the team, or simply a breath of fresh air — stand up and get a change of scene. Your mind will continue working on problems in the background, so you come back fresh with new insights.
Switch pairs frequently. Pairing helps to dissemimate knowledge throughout the team, whether that’s unique knowledge about the system (preventing bus factor problems) or deep-technical expertise. You can learn something from everyone: it’s incredibly insightful to see how someone else approaches a problem, the commands they use, even just their attitude. You won’t believe how many times you’ll have “I can’t believe I never knew about that” moments.
Write automated tests. Nothing builds confidence in your system like a suite of tests that check it works as it’s supposed to. When pairing, everyone has to be on board with writing tests. There’s been some controversy about how to go about it (and some healing). Test-first, test-after, or some other approach: you have to figure out what works for your team.
Try Ping-Pong Pairing. One person implements the test and the other then has to get it passing. Switch roles. Rinse and Repeat. This can be fun, and builds a nice rhythm to pairing.
Get plenty of sleep. Pair programming is learning on steroids. Sleep is the mechanism by which we digest and organize the flood of new information going into our brains. Too little and concentration, and decision-making suffer — not how you want to be programming. A former pairing partner used to dream he was an object being passed around the system.
Have fun. Pairing doesn’t have to be serious. It’s ok to lighten the mood with jokes or novel ways to gamify the process of programming. Your creativity and capacity for fun is the limit. Laughter and humour (especially if it’s related to the work you’re doing) have been shown to aid learning. Just make sure it’s not a work avoidance strategy.
Embrace diversity. Each of us has a unique, personal history. The more diverse our team, the more interesting perspectives we bring to bear on a problem. Enjoy people’s individuality. Celebrate their differences. This helps us overcome our innate biases.
If you’re new to pairing, or the code
Follow and absorb. Watching someone code is a high bandwidth experience — you can learn a lot. Do your best to follow along; it may seem fast and overwhelming at first but, over a number of days, things will start to make more sense. Gradually, you’ll begin to make sense of the smaller patterns (“ah, ok, that’s how I run the tests”, or “that’s how you launch the application”), leaving your mind freer to focus on larger concepts.
Ask questions. Why did you do that? What are you thinking? How did you know to start there? Notice the things you don’t understand, or that aren’t clear, then ask. This is a balance: asking too many questions can interrupt your pair’s thinking process, slow them down, and become a pain. Jot down a list as a reminder.
Say if you’re lost. There will be times — perhaps frequently — when you find yourself feeling lost or struggling to keep up. It can feel scary. That’s normal. Your pair should hopefully be sensitive to this. Part of becoming good at pairing is communicating honestly, so that together you can correct course and address any issues.
Get even more sleep. Seriously.
Be mindful of deadlines. In an ideal world, your pair would let you get up-to-speed, going at your pace. Unfortunately, sometimes the real world is not so ideal. Bringing on a new team member (even seasoned pros) will affect productivity but this must also be balanced with the need to deliver. Recognise that your pair is imperfect, and may be anxious or impatient as deadlines approach.
Advanced Level
Expand your pairing horizons. With a bit of thought and ingenuity, you can always find ways to level up your pairing. For several months I worked on a two-person project, pairing with the same partner, day-in day-out. Stupidly, we never took the initiative to rotate pairs with another team that sat next to us. It was a shame. Both teams lost out. If you’re working alone, the internet means that a pair is only a ping away.
Master your emotions. Ego, fear of looking stupid, boredom. You’ll meet your own demons every day. Don’t deny them. Learn to recognise them, and figure out strategies to mitigate them. This is a life-long challenge. Qualities to cultivate to be a good pairer: patience, respect, tolerance, humility, courage, honesty.
Notice how people think. Living, as we do, with ourselves the whole time, it’s easy to forget that everyone thinks and processes differently. Start paying attention to your pair’s thinking styles. Are you trying to fill the silence while they’re deep in thought, on the verge of a breakthrough? Do they need to go slower (or faster)? Do they understand better if you explain with examples? The better you understand your partners, the better you can work with rather than against them, and bring out the best for you both.
Work on self-awareness. The corollary of the last point. Knowing what you are like and what you need means you have a better chance of getting it.
Use language carefully. The way you say something can have a profound impact on how the message is received. Try to avoid phrases that involve judgement — “Why didn’t you just…” implies “You’re an idiot”. Instead try these:
- Have you considered…?
- A downside to that could be…
- I’m wondering whether this might work…
- What would happen if we did this…?
- Is it ok if we try…?
Local vs Global speed. People often mistakenly think that going as fast as they can (local speed) is best for the team. It’s not. Our goal should be for the team as a whole to create the most value as quickly as possible (global speed). There are lots of ways that people can fall into this trap, e.g.
- steaming ahead on the wrong things
- not helping to fix a broken build
- not stopping to address a key question from another team member
Say the hard thing. Pairing is a bit like a marriage: good communication, and compromise, is key. Your pair has BO, their breath stinks, or they have an annoying habit of getting food over the keyboards? We all have bad days, but if these things persist and bother you, it’s worth addressing them. It takes courage, but you’ll often be doing your pair a favour in the long run. Sometimes just getting it off your chest is enough to feel better.
Bend the rules. Pairing is an art, much like programming. Few rules are set in stone. Be open and willing to try new things. Notice the results — measure if you can — and keep doing more of what works.
If you found this useful please help spread the word by hitting the clap button below. Thanks!