Pairing
2012 was a huge year for me, I learned a ton and I want to capture some of that journey…
I was initially skeptical about pairing…it seems inefficient, right? Two people doing one person’s job? After those 10000+ hours of practice, I had good habits and a nice track record working solo, even remotely, for years at a time. I was productive even by my own standards and consistently exceeded expectations. However, like many uncomfortable things over the past year, I was determined to give pairing my best shot.
After nine months of consistent pairing I’ve found it’s probably the best way to write good software. I think I was still on the fence until we had a couple weeks at work where only one of us was there consistently for various reasons (vacations, holidays) and I lost 2.5 hours on a typo. Two hours beating my head against the wall for a typo in a javascript file. I had good unit tests, I just fat fingered a function call on the page. It never would have happened if I had my pair there. At that point it hit home - that’s one of the many things a pair provides: an extra layer of checks, a smart compiler, sounding board, real-time code reviewer, todo list tracker. It’s so much harder to make stupid mistakes anymore, much harder to lose 3 hours going down the wrong path. A pair stays focused; if one person’s attention wanes, the other person picks them up. I think once you pair with a person many times, you really get into a spot where you work very well together and fall into a natural rhythm, where you know who’s ready to type right now and who’s keeping an eye on things. Who’s focused on parens and who’s thinking about the design and where you’ll go next.
It’s kind of hard to find that rhythm, especially initially. I had a hard time not having my hands on the keyboard. I HAD to go home and hack a bit after work to stay sane. I transitioned directly from an environment where I was working 10, 11, 12 hours a day, just cranking out code every day. To go from that to “taking turns”, thinking about what I’m doing, explaining decisions, and brainstorming - it’s a big jump. It was very difficult for me to learn how to sit back and let someone else drive. I wanted to interrupt every key press. I’m still horrible at this. I’m bad about it in conversation, I’m bad about it when pairing. Luckily, I spend most of my time pairing with people that are easy-going and take my rudeness in stride.
I think the hardest thing about pairing is just keeping it going. We have to give it more than the 2 or 3 weeks we might commit to it starting out. On top of that, there are times when pairing doesn’t feel like the right thing to do. I’ve written emails with my pair, and it feels ridiculous. Sure, it’s good from a communication standpoint and a knowledge transfer standpoint. Its great to keep everyone on the same page, but I don’t feel like I provided a lot of value looking up some items in an excel spreadsheet. Likewise, there are some problems that are easier to deal with if you’re not pairing. Over the summer, we were searching for memory leaks and poring over heap dumps and log files. It was good that we paired on it so everyone understood the techniques and what we were looking for, but debugging problems like that often requires a holistic view of the system. The ideal state would be to engage what Andy Hunt would call an R-mode style of thinking and try to see the one clue that doesn’t fit. When I’m trying to keep a stream of conversation going, I can’t really “hear” that flash of intuition.
I think pairing is practical for many siutations, but you can try too hard at it. When I initially started pairing, my team was dogmatic about avoiding solo work. As needed, we would triple up and that was interesting, but HARD. It’s difficult to keep 3 people on the same page - the communication paths have tripled! It seemed like one of us would often zone out of the conversation for awhile. Nowadays, I would lean towards a 2 and 1 with promiscuous pairing, so we’re swapping a lot and one person doesn’t spend too much time on an island. Even if that one person doesn’t accomplish much, I think that’s probably better than trying to fight a wildly different dynamic. Trios can work by falling back on rudimentary pairing skills, maybe with round-robin style pairing, or pair coaching a third. If we’re writing code, if we’re actively going somewhere, I think it can work, but if we’re designing or figuring out the problem - it’s a committee at that point and we’re going to have a hard time reaching consensus on variable names, let alone anything more complicated.
It’s interesting how we can keep a constant flow of energy going - a full day “in the zone” - but when I step away I realize how much we’ve put into that and how burned out I am. It can be uncomfortable to be in someone’s space that long. I think that’s why people burn out on pairing, and save pairing for emergencies. It’s hard to do the extra steps that are involved in keeping that communication pathway open. And compromising! I’ll see something shiny that catches my attention and my pair will see something else that catches their attention and it’s hard to keep track of all the lines of thought. It was pretty hard to keep it all in my head when I was solo; I’ve always kept a notepad where I’d jot all my random thoughts and TODOs. I remember coming back to those the next day and having no idea where my thoughts were going. Now I find myself jotting down things my pair thinks of, and it really doesn’t make any sense because those thoughts were never in my head to start with.
Another double-edged sword in pairing is the differences in personalities. People have different work styles, different editors, different rituals. That’s part of the attraction of pair programming, a pair brings together different experiences to create a larger solution set. We don’t both reach for the same solution…but it does certainly make it more difficult at times. Some people have a higher threshold for boredom than other people do, some are more thorough, some like tangential investigations, some like tweaking UI elements, and some just want to do the bare minimum to get to done. It forces me to learn to accomodate and empathize, which is good, but it’s probably necessary to find a large pool of potential pairs to avoid clashing with someone too often.
I think even if two rockstars can produce more code solo, there’s something to be said for being accountable to my partner and how that constant code review keeps me honest. If my team has committed to TDD or simple design, or anything where there’s an extra responsibility to build a safety net and create readable code, then pairing is the easiest thing to do. Even if I’m committed to good practices, I might hack a little bit and tell myself I’ll fix it later. With a pair, now we’re in this together and we’ve committed to doing things the right way. When we inevitably have to make compromises to pragmatism, I have that extra reassurance that it was a reasonable step to make and that we did attempt to find a better way. On top of that, I want to understand what all the code I’m responsible for does. That may not be possible, but I still want to try. With pairing I was brought up to speed on a 80K LOC enterprise app to the level where I felt comfortable making big changes after a couple months.
One of the coolest things to experience is the way that ideas form. It might be the big thing people are missing about the pairing experience. It’s amazing how quickly you can build a transformational idea. I know very few people who can spout off a fully formed concept the first time. You can start with a whimsical notion, maybe a flash of intuition, and your pair twists it just a bit - “Well…what if we did this?” Then the light comes on: “Oh Yes, if we did that, then we can do this” and it flows into something special. You spend a lot less time typing but you get so much more done. As soon as one of us gets lazy and starts blindly writing plumbing code then the other asks “Why are we doing this?” and we’ll come up with something smarter or find we didn’t need it at all.
One of the hardest things to do on a development team is to share a new abstraction. It’s absolutely vital to gel on these things so the team can work at a higher level, but it usually takes a lot of time to get everyone to a shared understanding. An abstraction starts out imperfect and hard to grasp. However an abstraction developed by a pair has already withstood an initial hardening phase. It’s pretty good and has twice as many people that understand it as normal. Split that pair and you can double the knowledge again. You can iterate the design, or build on it to another level. Do you need design docs to capture your “architecture”? You need as many as you’d need if it was a one person team.
Most importantly to me, pairing makes me learn. I’m learning tools, shortcuts, and neat tricks. I’m learning how to be a better communicator and express what I’m thinking. I’m learning how to listen. I’m learning how to fail in front of others and take it in stride. I’m learning how feedback changes everything and how it accelerates everything I want to do. I’m learning how I don’t have to know everything to succeed. I’m learning how to discover and evolve.
Thanks to all that have taken the time to pair with me.