I cannot, for the life of me, fathom how anyone can like pairing. I’ve done it, and with one person in particular, it was tolerable. We got along well and worked effectively together. With everyone else I’ve tried it with, it felt pretty bad. Either basic interpersonal compatibility problems or extremely different approaches to writing code.
I’ve found pair programming to be an intense form of sharing implicit cultural rules, and that many of the benefits of pair programming can be accomplished by formalizing what behaviors you want your team to follow.
Something I’ve found that’s worked well for this is team code reviews - basically a team (probably max 10-12 people) sit in a room for an hour and review a piece of code. The idea is not to tear someone apart, but rather to give constructive criticism, highlight good work, ensure that standards are being adhered to, etc. May not work for everyone, but when I’ve used it in the past it’s worked well. Probably not something to do for the duration of an entire project, but it’s a great way to get a team working well together at the start.
I felt this way until I tried it and I love it. But maybe it’s because I get along great with my team? If you don’t mesh well with your coworkers I can see how it would be terrible. But I started out the only developer at my company and have gotten to have a say in every hire, and as a consequence get along great with all of them.
I don’t know that it was your intent, but your sentence structure implies that if someone doesn’t support pair programming it is because they have a poor relationship with their team.
I love working in the team that I have been working in for the last four years, and I feel that we have a great team dynamic. Even though we get along, I don’t believe pair programming would help us produce more or better quality software than we are currently producing through other means; e.g., primarily asynchronous code review, increasingly rigorous static analysis tools, and more design and exploration up front.
I think pairing is exhausting for introverts, and I have no particular drive to agree on a text editor or a shell or a font with my colleagues when we need share precisely none of those preferences to be productive as individuals in a team.
I don’t think that’s the only reason to not enjoy pair programming, but it’s certainly a reason. I would not attempt to give a full account of all the reasons in a single comment. :P
I’m classified as an “introvert” too (though don’t get me started on trying to classify personalities, which are flexible and context-sensitive things into static categories), but I still enjoy pair programming. It doesn’t require you to be an extrovert.
The things you mention not wanting to agree with your team on (editor, font, shell); first off I’d argue there’s no reason you have to compromise on those things. You can run your own shell with your own font and so can your teammates. You can use your own editor as well.
Second, as I’ve gotten older I’ve cared about those kinds of things less and less. The benefits I get from pair programming are so much more important than whether I’m using SublimeText or vim, or what font I’m using.
Of course you have your own priorities, but that’s my personal experience.
Pairing is the fastest way of teaching I’ve discovered, and I love the satisfaction of seeing a teammate get confident with something quickly.
Other than that, I find it mentally and emotionally taxing, and the ergonomics rarely work for me.
Like I mentioned in the post, I think pairing is a skill to learn. Most developers (even if otherwise amazing) will be terrible pairs on week one. By six months, most will be pretty great if given good feedback.
This was listed as a “pro” of pair programming:
No one cares if a task is rejected by QA
I read this as indicating that poor quality output didn’t bother anyone.
I think maybe the author meant: “No one’s feelings are hurt if a task is rejected by QA.”
That is what I meant. It’s a lot easier to see a rejected task when it’s not “your” task. It helps take a lot of the ego out of it.
I think that’s possibly the best effect to happen by default. Interestingly, the organizations of the past that produced the highest quality had varying approaches on this topic. Here’s a few in no particular order.
Fagan Inspection. Code a bit then specific amount of time for code reviews often with list of common problems. Emphasis on fixing problems collectively rather than blaming people. Worked well. Similar to your statement.
Cleanroom. The design method and coding guidelines w/ verification conditions meant the code was often correct-by-construction if high-level design was correct. That’s if they applied it right. Verification team assessed that after coding. The techniques were main source of quality improvements but many noted there was a sort of stigma if you had to start over after failing verification. That this embarrassing event happened rarely increased developers commitment to good code. Opposite of your statement.
OpenVMS. Alternated by week where they build a week, run tests on weekend, do a week fixing what they can, and repeat. Excellent reliability. Overall effect was like with Fagan and your statement.
Orange Book B3/A1-class. These were done using formal specification, verification, testing, review, the works. All confirmed by review and pen tests of a third party. They usually had formal methods and coding teams working side-by-side finding inconsistencies. Overall effect like Fagan and yours where getting it right collectively mattered. At independent review, it was embarrassing and expensive to have them find significant errors with scathing comments from evaluators requiring costly corrections. Opposite of your statement in that effect.
I see little consistency in figuring out whether lack of blame or assigning it is more powerful motivator. Probably varies situation by situation. One thing that worked well enough is ignoring it within development and verification teams while keeping them mentally separated from the work. Constant reminders that it’s a collaborative development and learning experience help. I also suggested long ago anonymizing where a bug came from and who fixed it. Never tested that concept, though. Also, all high-assurance work showed development and QA needs to happen side-by-side with much collaboration to (a) make each enable the other with coding/testing style and (b) prevent wasted opportunities due to misunderstandings.
So, those were my takeaways over time on the structure of verification and effect of blame. More like a tired brainstorm trying to remember them than a carefully-revised one.
It’s a better write up than most I’ve seen. I like the overall collection of attributes, pro’s, and con’s. As an opponent of production pairing, there was one thing I didn’t like: implication that people only dislike pairing for personal reasons. There’s years of research and many anecdotes covering both the concepts of flow as a productivity tool and multitasking as a disruptor. Flow is this type of focus that kicks in a while into working on something that amplifies the programmer somehow. Interruptions, like phone calls or someone talking over your shoulder, can jolt you out of it in a way that take time to recover. People in closed, office spaces manged to get in that state more than open ones with many interruptions. Multitasking studies similarly showed that people always did worse when they had multiple things in mind despite often thinking they were doing better. Many pair programmers have described how the process makes them simultaneously work on programming and anticipate other’s thoughts. This distraction might affect the flow concept as well. The book Peopleware was my first introduction to these although I had already experienced the effect many times.
So, years of studies showing the ability to focus uninterrupted for periods of time improving productivity, any interruption having negative impact, and multitasking having negative impact make me oppose a programming style that integrates these. I’ll throw in the additional point that introverts, common in programming, have brains wired to be hit with this more where they like quite spaces where they’re in the zone on the problem. They often outperform others on that problem as they seem to exemplify using flow to soak up or produce information. Regular, social interaction also drains them to the point where they need to be alone to recharge. This makes pairing look almost scientifically designed to waste several of tech’s great resources at once. Again, being an introvert, I had first hand experience in the claims of various studies and authors I read.
That said, I do find some potential here. I’ve read accounts of people becoming better programmers by spending some time pairing with… better programmers. Whether watching or being watched, they learn more effective ways to express solutions to various problems. An introvert or flow-using extrovert can benefit from this is it’s just a small amount of time. Methods like Fagan Inspections and Mills' Cleanroom showed most of benefits of incremental, quality-centric development (eg Agile) in 1980’s without pair programming. Increments, expectations of QA work, and team responsible as whole for code achieved many listed benefits in this article without pairing downsides. Finally, I think some experiments are in order to see (a) if extroverts who love social interaction adapt to maintain flow during pair programming and (b) controlled experiments to see if they’re really more productive that way vs non-pairing increments w/ rotations and a statically-cheked. coding standard.
So, years of studies showing the ability to focus uninterrupted for periods of time improving productivity, any interruption having negative impact, and multitasking having negative impact make me oppose a programming style that integrates these.
I’m sure this varies by personality, (I’m strongly introverted FWIW) but my own experience has been that I am a lot less distracted when I am working together with someone else. To be honest, pairing often puts me in such intense flow that I can’t do it for more than half the day without ending up completely exhausted by the end; I have to be careful to remember to take rest breaks, etc.
I would strongly question whether the flow is exhausting, or if it could instead be the protracted period of forced social interaction. I find serious flow when working in the quiet by myself, but long, contiguous sessions of talking and interacting with others can be pretty exhausting – to the point where a full day meeting or workshop can sometimes have me feeling ready to collapse in bed by afternoon tea.
Well, often we would have pairing sessions where the flow just wasn’t happening for whatever reason; maybe interruptions from service alerts or dealing with flaky CI servers or something. In those cases I did find it less exhausting than heads-down coding. It was also less frustrating than working through the same problems solo, because you could let off steam by joking about it or whatever.
I agree that protracted social interaction in larger groups can be exhausting, but on a small team where you know your teammates really well I never found it to be the case other than with specific individuals who had a hard time working on a team. In this case there were serious efforts made to ensure team cohesion, including week-long face-to-face meetups (we were an all-remote team) where we would rent a house and plan for the future or tackle specific technical challenges.
The intense flow to exhaustion is very common in developers new to our team. It takes somewhere around 6 months to build up the stamina to go all day for a week without going home a zombie :) It is also why we work a strict 8 hour day and all vanish at 4:30.
When I did this, it was actually on a remote team where half was on the US west coast and half on the east coast. We paired when timezones allowed for overlap and spent the rest of the time solo doing research, emails, spikes, etc.; it worked really well.
I appreciate the reply! I’m quite interested in looking into the various methods suggested in your earlier comment.
There’s absolutely a big loss of “slow thinking” that happens when pairing. Most thinking is fast, conversational, and fluid. Depending on the work, this side effect ranges from debilitating to inconsequential. A good portion of our work would be classified as CRUD, and as such requires no real deep thinking.
Tech debt, ORM changes, root cause analysis, and concurrency work do require deep thought, so typically we will go “odd” to think and prototype these ideas alone. When we’ve got a good prototype, we review it with a partner and then throw it away to be implemented in the pair. We find this a good way to ensure a tricky problem gets prototyped and thought through before going into production.
The referenced white paper about promiscuous pairing had some small sample findings about pairing and rotations, but I’ve not seen much else other than that and a few small studies of college students. The studies do seem to indicate pairing is slightly slower than the two working separately, but brings higher quality. None seem to test with just randomized task switching, that would be fascinating. I suspect it could work well, with the right group and culture in place.
I didn’t mean to imply that all developers who hate pairing only do so for social reasons, but so far all I’ve met hate it first, then afterwards search for data to validate their feelings. Anecdotally, I loved it first, then went looking for data to back it up second. I’ve met a quite a few who hated it first, then over six months gained skill enough to where they don’t want to work in any other way.
There’s another aspect at play, and that is one of happiness. I’ve yet to see a code review system that is both effective and enjoyable. The ones I’ve seen are either low value (style and variable-name preferences) or long and boring, requiring complex write-ups and multiple repeat submissions.
Pairing for us is enjoyable, fun, and often light-hearted. Review comes every half day when we rotate, and typically only requires a few minutes of commentary by the developer who stayed on the task (when we rotate, we try to ensure that a developer stays two sessions in a row, one to learn, and one to teach). If two of the team thought a strategy was a good idea, then it typically doesn’t need a major directional shift. If it does, it’s only four hours of work. By the start of the second day, three developers have “put their name to it” so it’s much less likely to need a major change.
However, like I said in the post, I think trying to force this on developers who hate it is a massive mistake. No one should have to pair if they don’t want to, even if it was provably superior, which it currently is inconclusive. Pairing is very intimate, typically requires close proximity, and a complete exposure of all your weaknesses, and would be brutal to force on people who don’t want it.
I think what little data exists is inconclusive enough to indicate it is largely a preference issue. In our case, we prefer it, so we do it. It has great knock on effects that have kept us competitive years later.
I thought it was interesting that people spend less time on Reddit/whatever, but tasks still take longer to complete. Although, the author is unclear on what “longer” means. Longer than they could take or longer than they would take if they were not pairing at all?
Personally, I don’t like pairing. I find it puts a lot of focus on, what I consider, the least interesting aspect of the whole ordeal: programming. I enjoy pair problem solving and I’ll pair program if there is a distinct focused task to solve, or mentoring or being mentored. But generally I enjoy getting a problem, discussing a solution together, then implementing on my own. To stay focused I just use a timer to focus for 30 minutes or so, take a break, rinse repeat.
Tasks taking longer to complete happens only occasionally, and usually around difficult tasks. I’ve seen that many individuals rarely prototype as much as they should, and so often just go with “whatever first worked”. An adequate first design means that perhaps task 1 is completed sooner, but tasks 4+ in that same area take longer and longer.
When we rapidly switch, tough tasks sometimes get prototyped several times before an ideal solution is agreed on. Ideally (but probably not always) this means that task 1 is slower, but tasks 4+ are not impacted.
When comparing pairing vs not pairing, we think pairing is still faster across years, and more enjoyable. More enjoyable means people stick around longer, which greatly increases their productivity.
I’ve generally refused to work in environments where I would be expected to pair. I distinguish that from informally sitting with someone and poking at code together.
Put bluntly, if you can’t trust me or my colleagues enough to code on our own and present a well done piece of work for peer review and deployment, then I don’t think I want to work for you. I’ve spent enough time with other professions who operate at high skill level - pairing is incredibly uncommon for how high-level competent professionals work.
So. Glad it works for you, please don’t call me.
Right off the bat I think that’s the issue, there’s not a “you” in the sentence of “if you can’t trust me and my colleagues”. The team votes and continue to vote for keeping pairing as the intersection of the most features, the fastest training, the highest quality, and the most fun.
If we were being forced and hated it, that would be terrible, and a sign of deep-seated mistrust. I’d hate to work on a team where I was so mistrusted, regardless if they made me pair, or whatever it was. That mistrust would infect my every interaction with the company.
I also think the comment about how high level professionals work isn’t quite accurate. When dealing with new, difficult projects, I’ve heard of doctors, engineers, and lawyers all have some form of pairing. Much like with most software jobs, a lot of those jobs is fairly well-known, and making a mistake is low risk. When it’s less well-known, or making a mistake is high risk, teams tend to work closer together and heavily check each other’s work.
I don’t think there’s anything wrong at all with saying “I never want to work on a project that’s high risk.” It’s a lot more hassle and a lot more tedious. Pairing isn’t the only or best way of keeping down risk: many others exist that involve a lot more headache.
Also, there’s nothing wrong with never wanting to pair. The work day is a huge chunk of our waking time, may as well let everyone have their favorites. Some of us love pairing, and took (and keep) this job because it’s important to us. We ensure every candidate who accepts a job with us knows what they in for: an eight hour day pairing is the interview. This way we all get what we like: the few of us that love pairing should get to keep doing it, and the majority that don’t shouldn’t have to.
I’ve found that a lot of friction around pair programming comes from its uncomfortable physicality (proximity) and the need to cope with a new work environment – a different keyboard layout, different OS, etc. I’m more on the introverted side of the curve, so I can imagine that pair programming at the same desk can be a very unpleasant experience for many people.
However, remote pair programming on a shared development machine using tmux and a ‘standard’ editor (vim/emacs) seems to hit the sweet spot for me. Both programmers get to remain in a comfort zone physically at their own workstations, but still gain the benefits of joint attention. My experience is that the sense of team ownership and knowledge transfer is worth the extra burden. Getting a uniform development environment set up means onboarding new devs is easy and can be undertaken by multiple team members.