Together—one of the most inspiring words in the English language. Coming together is a beginning; keeping together is progress; working together is success.
—Attributed to Edward Everett Hale, nineteenth century author, historian, and Unitarian minister (http://bkaprt.com/ppp/01-01/)
Computer programming has historically been seen as an individual effort. Time on the old mainframes was parceled out individually, and workers with more standing got higher priority. For decades, the stereotypical office has been made of cubicle walls and PCs—personal computers. Not sharing a computer has been an unwritten rule for nearly fifty years.
It’s interesting that, even though there is hard research showing that most people find pair programming...MORE enjoyable than working alone, a very vocal minority on twitter says that programmers can never work effectively with other people. (http://bkaprt.com/ppp/01-02/)
The prevailing sentiment in the business world seems to be that technologists don’t want to collaborate. Meetings waste time that could be spent pounding out lines of code. It’s true that many programmers treat work like a maximization exercise: get as much compensation for as little risk and effort as possible. The problem I see with this approach is it reduces programmers to little more than machines themselves; even brilliant programmers are likely to plateau under these conditions.
Pair programming as a practice emerged from a subset of Agile methodology called Extreme Programming (XP), a set of human-centered software development practices that offers validation for bringing communication, simplicity, feedback, courage, and respect to your work. In my experience, it’s been far more fulfilling than slogging through code on my own; I want to bring my whole self to work and learn from active collaboration with smart people. Beyond personal growth and fulfillment, the shift to pairing also brings forth improvements in team cohesion, clarity around business goals, and even produces better code. Here’s how.
Better Code, Better Outcomes
If more computing power or faster typing was all it took to ship software faster, you can bet we’d have a supercomputer on every desk and programmers would be hired by typing test, but in reality, a programmer who types 20 percent faster isn’t going to be 20 percent more productive. Critical thinking, problem solving, and quick recall make up the majority of our effort. Producing lines of code isn’t the objective—it’s just the means for attaining the real objectives: correct business logic and intuitive user interfaces.
A second pair of eyes can catch a missing semicolon or find that single-character difference that is failing your test, but much more important than catching typos are the decisions that can’t be caught by a linter or compiler. A second brain helps you give good names to classes, methods, and variables and write clearer documentation. It gives the pair enough headroom to think about architecture, apply helpful design patterns, and sometimes even come at a problem from an entirely new angle. It means you’ll think through more edge cases in your business logic and have twice the empathy for users as you design how they’ll interact with your software. Having twice the brain power is much more important than twice the fingers.
At Promptworks, we’ve observed that having a pair is not noticeably faster or slower than two individuals working independently over a short period of time (like an hour or four). In a 1999 controlled experiment in a classroom setting, Dr. Laurie Williams found pair programming took a team about 15 percent more developer hours than working as individuals. However, she found defects to be 15 percent lower, design quality higher, and the project completed in 45 percent less calendar time (http://bkaprt.com/ppp/01-03/, PDF).
- Coordination costs. Two programmers working on two copies of the same software have to plan what each will work on, resolve conflicts when they both touch the same part of the codebase, and read the changes that others have made so their future work takes it into account. With pairing, you’re working on the same copy of the software, and you’re both aware of how it’s changing in real time. There are no merge conflicts between the two of you, nor catching up on what the other did.
- Thinking through a problem twice. A solo developer who needs her code reviewed will have to revisit the problem, explain her approach, and rationalize the solution to the other developers. Some of them may revisit the paths that she already eliminated. Unilateral decision-making is a genuine risk, but the need for code review strongly points to pair programming as a more efficient and less antagonistic alternative. Why have two sets of eyeballs looking at the code serially when they could be in parallel? By working together from the outset, you can avoid thinking it through twice and move on to the rest of your long list of features.
- Throwing away work. The better designed and built the software is, the longer its life and the more adaptable to changing business needs. Building the components of a sophisticated asset in silos and then expecting the resulting amalgamation to work optimally is a recipe for having to throw it away and build a new solution much too soon. Worse than the cost of replacement is the lost revenue when software can’t change fast enough, holds back the workforce using it, or creates a costly security breach.
When pairing, you have a partner who holds you accountable and doesn’t let you get away with lazy thinking, uncertainty, or failing to recognize the merit of your accomplishments. You hold yourself to your own professional expectations just by having someone hear your thoughts. It helps you live up to your potential, as software engineer Sarah Mei observed after pairing full-time for two months at Pivotal Labs:
Fundamentally, what I love about software development is writing code that people actually use. I love to finish things. So anything that makes me feel like I’m really [getting stuff done] makes me incredibly happy.
When people talk about pairing, you hear a lot about how it “amplifies” their productivity. I am going to go on record with the truth, however. Pairing does not amplify my productivity. Instead, it erases all the bad habits I have that keep me from being a superstar on my own.
When I’m pairing, I can really get shit done. (http://bkaprt.com/ppp/01-04/)
Pairing is synchronous, so a person—not a deadline—is your reason to show up on time and not zone out as the mid-afternoon doldrums set in. You can help each other remember to take breaks, eat lunch, and time-box your code spikes. Even the most scrupulous developer is sometimes tempted to skip writing tests under pressure or move on before refactoring code.
“Pair pressure”—the best kind of peer pressure!—can help you avoid the bad habits that keep you from being a superstar programmer:
- Acting on first impulses. In your zeal to solve a problem, you are likely to try the first approach that comes to mind. By having to jointly negotiate how to approach the problem, you’ll evaluate more alternatives within a pair than you would individually.
- Rabbit holes. Sometimes you spend too much time digging into a problem that doesn’t really need to be solved right away. Your pair can help you see when you’re getting in the weeds and excavating pointlessly.
- Distractions. Focus and a state of flow are critical to doing your best work. There’s always a temptation to scroll through Instagram while the computer does the work, but pairing encourages sustained attention to the work at hand. While waiting for tests to run, you can talk about the problem, discuss what you’re planning to do next, or look at the backlog together.
- Cutting corners. When your estimates are too optimistic or you feel guilty for having gone down a particularly deep rabbit hole, you may be tempted to make up for lost time by skipping the writing of tests, implementing only the happy path, or not giving attention to security. Your pair can be the angel on your shoulder, reminding you to do what’s right.
- Fear and shame. Solo programmers lose time worrying whether they’re right. They’re afraid of looking foolish, making the wrong choice, or overlooking something that might seem obvious. A pair can piece together enough knowledge to feel confident that they’re right—or admit when they can’t figure it out! The rest of the team is more likely to trust the decisions a pair made because there was already some level of discussion, deliberation, and agreement.
- Getting too clever. Pairing can provide a shared commitment to pragmatism and levelheadedness that those who have to deal with your code, tests, and comments later will appreciate. Don’t get me wrong—we use funny fake names all over our test code and documentation. But hopefully, your pair will stop you before you name a class
AbstractInterceptorDrivenBeanDefinitionDecorator(classic Java Spring framework nonsense!) or write your own encryption function (utterly irresponsible foolishness!).
Better code and more productivity should be an easy sell to any boss who needs at least two developers, particularly one who feels anxiety about the team’s “bus factor”—a macabre but memorable metric for how concentrated the team’s skills and project-specific knowledge are. What happens if the dev who hoarded all database work gets hit by a bus, or bitten by a badger? (My team is trying to make “badger factor” a thing.)
Pair programming reduces the team’s reliance on one or two superstars, and even very similar developers who pair will discover strengths and knowledge they didn’t know the other had. Other team-strengthening benefits accumulate with each project:
- Learning new tools. Over many years, we develop our own code manipulation habits and style. Good pairing can teach you better, more efficient ways to use your tools. If you’ve used the modal text editor Vim, for example, you can imagine how pairing with another Vim user could make you more efficient (or if you wanted to try Vim, how pairing would make it less daunting).
- Providing hands-on training. Like learning to speak a foreign language, you haven’t really learned any new software language or pattern until you’re able to produce it yourself. Seeing it done isn’t enough, but working it out by yourself is often difficult and inefficient. Pairing is the perfect in-between.
- Developing your own best practices. You naturally converge on a set of conventions and good habits without needing to write a style guide or have a manager dictate best practices (a.k.a. “the way we did things when I was a developer”).
With the expanded knowledge base that comes as a side effect of pair programming, every member of a team can become comfortable working in any part of the app, or at least be intentional about learning what is needed to become so.
Pairing Keeps You Engaged and Fulfilled
It’s great that pairing makes for better code, air-tight business logic, more intuitive user interfaces, less time being sidetracked while simultaneously building up your team—but even if none of that were true, I would still want to pair because it’s fun!
Maybe it’s just my work style, but I like having someone with whom I can process thoughts. I like piggybacking on my partner’s ideas to come up with the best solution. The synergy gives me energy and pairing feels like an activity worthy of my time. I can stick with hard problems longer when I have a partner and accomplish big things with what feels like little effort.
Pairing deepens your appreciation for the work itself. Clients or superiors can appreciate the result but probably won’t celebrate the little victories with you along the way. Your partner gives you an incentive to do the little things right and maybe even show off a little bit.
You need to play around with stuff and do silly things to learn. There’s a whole class of actions you just don’t take when pair programming either because you consciously or subconsciously censor them out…I think it should be the main way all production development takes place. (http://bkaprt.com/ppp/01-05/)
Humans are meant to work together. Being given one task at a time to perform in a solitary bubble goes against how humans have been productive for millennia, so why should we accept this approach in software development—especially considering the high cost of mistakes?