Pair Programming Misunderstood
How I thought it wasn't for me, until it was.
This tweet on pair programming has created quite the stir on social media last week:
As you’d expect, the responses have been varied, from emphatic agreement to vociferous disagreement, including everything in between. Many of those who fell in the latter camp have already written response threads dismantling the above argument line-by-line, so I won’t be doing that here. Instead, I’ll share how I started pair programming, and some of the “aha” moments I experienced along the way.
What is pair programming?
Pair programming (AKA “pairing”) is two people programming, with one person typing at a time. Understanding this definition requires one to appreciate that programming is more than just typing, and appreciating this difference is necessary for being convinced of the merits of pair programming.
What is programming?
Fundamentally, programming is the process of identifying and solving problems through the authoring of computer instructions (AKA “code”). Getting these instructions right requires that programmers identify the problem with absolute precision. Within the scope of the problem at hand, this means articulating exactly what the computer should do under every possible circumstance — computers have a zero tolerance for ambiguity.
Further, code is written to be executed by computers as well as comprehended by humans. It is the latter that makes modern software engineering especially challenging. As Martin Fowler said,
Any fool can write code that a computer can understand. Good programmers write code that humans can understand.
Code readability, however, is only a means-to-an-end to writing code that is easily maintained and extended in response to new circumstances. The accelerating pace of change in software means that the need for well-designed code will only increase.
Thus, software programming in the modern sense is a tall order. Let’s say that you can figure out exactly what the computer needs to do and exactly how to instruct the computer to do it. How do you know that the code you have written is readable to other software engineers? How do you know that your design is simple, yet scalable?
A few answers to these questions exist. Other than pairing, code reviews and general programming experience are two that come to mind. Pair programming is not the only way to write readable and scalable code. Still, many claim that it’s the best way we have so far, compared to the alternatives.
How I started pair programming
I regret that I wasn’t more curious about pair programming when I first learned of it back in 2007. The long-forgotten article I read explained that pair programming involved, “two people sitting at one computer, with one person having control of the keyboard at a time.” That sounded awful! Even back then I knew how I liked to write code: without interruptions, immersed in my “flow state”, and (most importantly) alone. So I dismissed the outlandish concept without giving it any further thought.
Six years later I was faced with pair programming once again when I began working on a team that paired all the time. At first, I hated it. The experience felt like my thoughts were being trampled over.
Intention and reflection
Then, I began to pair with another Software Engineer who was more experienced at pairing than those who I had worked with so far. Instead of “talking over” my thoughts — telling me to do something different from what I was thinking — he gently pointed out that he was unable to read my mind and if I’d be so kind as to tell him what I was thinking.
That was my first “aha” moment when it came to pair programming. Along with other insights, it led to my team developing the approach of Intention-Driven Pairing. In addition to setting intentionality around how we worked together, the approach gave us an opportunity to share feedback after every pairing session, so issues such as a lack of “thinking aloud” were identified and addressed early.
A year later, I had the opportunity to attend my first Coderetreat. There, I paired up with someone I had never met (let alone programmed with) before. I was worried. On the one hand: I knew how to pair with my teammates, thanks to hundreds of hours of pairing together. On the other hand: I couldn’t see how pairing with a complete stranger was going to be any different from the first time I tried pair programming.
Then, they introduced me to ping-pong pairing.
This was another “aha” moment for me. Novices at a given skill need a clear set of instructions (or rules). By following these instructions repeatedly, they establish a baseline skill level. Musicians play scales. Athletes do drills. Programmers do code katas.
Pairing styles are instructions for novice pair programmers. Ping-pong pairing is an example that is particularly well-suited for programmers who are new to both pair programming and TDD, as it uses the red-green-refactor cycle to ensure that control is frequently rotated between programmers.
I did not enjoy pair programming when I first tried it. I am also still learning how to be a more effective pair programmer. Nonetheless, my most fulfilling, insightful, and productive programming moments have happened in pairing sessions. The pair programming learning curve is steep, but I think it’s worth surmounting.
In a future post, I’ll delve more into pairing styles and why I think they’re the key to effectively introducing novices to pair programming. If you’ve already dismissed pair programming as something that’s not for you, I hope this post has opened you up to the possibility of having your mind changed.
For more on this, see my prior post on Learning Frameworks for Skills Acquisition.