This blog is mostly geared towards Software Engineers, also known as people who are called engineers but should definitely not be trusted with making sure a bridge does not collapse.
Recently during one of our retrospectives on the ScriptRunner for Confluence team, our very own Sherry Yang brought up the idea of doing pair programming again. Immediately, Aidan Derossett’s ears perked up and he began frothing at the mouth, as those two simple words had triggered the thought of a career-long dream, four years in the making.
My immediate reaction to Sherry’s suggestion, however, was basically this:
There’s something about the phrase “pair programming” that activates my lizard brain’s fight or flight mechanism. Okay, fine, I’ll admit that’s a bit dramatic… but I’m not completely alone in having a visceral reaction towards pair programming. In an extremely scientific and totally representative poll of developers at Adaptavist, we found that 19% of respondents didn’t find pair programming personally useful. Another 35% said they did find it useful, but didn’t think it was always implemented correctly.
Having combed through the ensuing discussion after the poll was conducted, there were several reasons respondents gave for having qualms about pair programming. The ones that resonated with me personally, though, were this:
- Varying difficulties of tasks don’t necessitate pairing on every issue, causing sprint velocity to slow
- Pair incompatibility
- Conflicting communication styles, ineffective sharing of ideas, wide knowledge gaps, etc.
- Difficulty staying “in the zone” & performance anxiety
- Not enjoying the experience of someone watching you code / having feelings of inadequacy or being “exposed” for your lack of knowledge
In talking with Sherry Yang, I realized most of my attitude was developed as a result of a combination of the above. It’s not that I fundamentally disagreed with the premise of pair programming. It’s just that I… never really had a good experience with it. All too often throughout university, I was paired with people who were all too quick to stare over my shoulder and tell me “HEY! YOU FORGOT A SEMICOLON THERE!!!”, rather than actually try to communicate through difficult problems. Pair programming doesn’t have to be that way, though. There’s a better way of doing it, on your own terms.
Thanks Sherry. Healthcare isn’t free here in the USA, so feel free to bill me for an hour of therapy.
Having expressed my strong opinion about how much I disliked pair programming, I felt that I needed to do something about it. It’s generally not productive to complain about things without having any sort of better idea. I’m not certain, but I’m pretty sure that’s a quote from Jonny Carter.
So, the following sprint after Sherry Yang gave her suggestion, Aidan Derossett and I volunteered to pair first and report back on how it went. Pairing with Aidan was intentional, because he had previously discussed his extremely positive experiences with pair programming. In contrast to my own perspective, Aidan wasn’t going into this with any negative connotations and could potentially draw from his experience to improve our pairing experiment. Besides, convincing Aidan to participate in a sanctioned event where you spend multiple hours talking with someone to solve problems was probably the easiest task of my entire life.
With that agreement in place, Aidan and I began with some questions:
- What things do we want to avoid?
- What things do we want to make sure to do?
- How can we facilitate virtual pairing as in-person meetings are not an option?
- What issues will we actually pair on?
- How will we know if we’ve had success?
Drawing on our own past experiences from pair programming, there were some things we wanted to avoid. Remember: there isn’t one right way to do pair programming. You can totally do it on your own terms and omit the things you don’t like.
- Pairing on issues that really didn’t require elaborate discussion (e.g. minor bug fixes)
- Needless pedantry about how code is written
- Mandatory/forced pairing
- Undefined or open-ended pairing sessions
The fourth point was especially important to us. While we are capable of getting on a call and chatting all day (believe me…), that’s probably not the best use of time. Each person should come with a specific challenge that they’re ready to discuss and solve.
While there was some negative things about pair programming we wanted to avoid, there were definitely some good things we experienced that we wanted to incorporate:
- Use pair programming as a chance to unblock ourselves (as not to depend on PR reviewers or Senior Engineers)
- Sharpen our technical communication skills
- Be unvarnished in our curiosity about how the other person actually develops (what does their IDE look like, how do they think about problems, what convenient shortcuts they use, etc.)
- Try new live coding technologies
- LEARN SOMETHING NEW
We decided we’d give IntelliJ IDEA’s new Code With Me (CWM) plugin a try. It’s a recently-released feature from JetBrains that allows you to collaborate within your IDE with someone else, in real time. You can use the Code With Me plugin to share your locally running project with anyone. Code With Me is good for real time collaboration, editing code, sharing a server, and running a debugging session. A Code With Me shared session involves the interaction between a host and one or more guests. If you use VSCode, their analogous feature is Live Share.
Having updated our IDEs to the newest version and installed CWM, we were ready to begin. You can start a CWM session by simply clicking on the icon within your IDEA. It’ll ask you what permissions you want to give your participants. Aidan is highly trustworthy, so I gave him FULL ACCESS to my entire machine. Do this at your own risk…
Once the session is started and you copy the invite link, you can send the link to the participants so that they may join. For added security, CWM will ask you to verify their identity as they join:
What’s really interesting and convenient is that CWM has built-in video and audio capability. So, no need to fire up Zoom. Here’s what that looks like:
The rest is sort of self-explanatory. You can both write and edit code at the same time and you’ll see each other’s cursor & code changes simultaneously. Since I’m a benevolent dictator, I used the “Force participant to follow” feature. That automatically changes your participant’s screen so that you’re always looking at the same file. It’s nice for making sure everyone is on the same page - literally.
While the built-in audio/video was convenient, it often disconnected. We aren’t entirely sure if that’s a problem with CWM, though. I have notoriously unstable internet. Code With Me seems to expect a 100% continuous connection, whereas Zoom seems to be able to buffer and auto-reconnect. Code editing seemed to work perfectly fine.
CWM isn’t perfect, but Aidan and I would rate it a solid 7/10. It does what it promises fairly well, but some of the ancillary features (chat, audio/video, etc.) aren’t as strong. We expect it to improve over time.
If nothing else, it’s a fun thing to try with someone. We’d recommend giving it a go!
With our Code With Me environments set up and with some guidelines in place, Aidan and I began our pairing exercise starting with his issue. If you care to know the specifics, this particular issue has now been released to the public as a new SR4C feature.
Because this was Aidan’s issue, he was the designated driver. There are a lot of definitions around the concept of “driver” vs. “navigator” in pair programming. That being said, we didn’t really concern ourselves with specific semantics. By driver, we simply defined that as the person who has ownership of the particular problem. With that in mind, Aidan began by explaining the context of the particular challenge he was facing. He didn’t go into a mind-numbing amount of detail, but it was definitely deeper than just a surface-level description of the problem. This allowed me to immediately recognize why this was a good opportunity for pairing. Aidan didn’t simply need to know what to name a variable - he was facing some really tough architectural changes that needed a proper discussion. Because of that, here was the general pattern we followed:
- Driver comes to pairing meeting with specific challenge & gives context
- Driver discusses with their partner; partner offers input on solutions or design
- Partner either writes code themselves for the driver to see; or explains to the driver what should be written
- Discussion ensues; solution is agreed/iterated upon
- Process repeats
This worked out great for us in the three to four hours we spent pairing. I offered my insight on what I thought his solution could be, and we both learned from each other in the process of debating & discussing.
Some weeks later after my vacation, we repeated the same process for my issue. My problem was somewhat different, as it was about 98% discussing what to do and 2% actual coding. Despite that, it was still an incredibly informative pairing session. I came away with a very clear understanding of what I was trying to solve & what the experience would be like for the user. Even though I didn’t walk away from the pairing session with code that could be directly committed, that really wasn’t the most important thing to me for the pairing session.
We don’t think every pair needs to strictly follow the above pattern, but it worked for us and we think it could be helpful for others to try it out.
Defining success with pair programming is actually kind of tricky. If one or more of the participants despised doing it, but the code came out better, is that a success? Conversely, if both people enjoyed doing it, but the code came out slower and/or worse, is that a success?
We don’t really know for sure, but we generally think successfully pairing has the following outcomes:
- If given the opportunity, both participants would willingly participate in pairing again
- Both participants furthered their communication skills in some way
- At least one participant gained some bit of knowledge
- The resulting code quality was higher
- Note: We think time is a factor, but shouldn’t be determinative as it relates to success. If the process took longer BUT the code quality was the same or better as if it was done solo, we still classify the pairing as a success.
Given the above outcomes, Aidan and I checked every single box. We believe our resulting code was better. We definitely learned something from each other. Our communication skills regarding technical concepts were sharpened (not that they weren’t as sharp as a fine Japanese sushi knife already). If given the opportunity, we’d definitely pair again. By that measure, pairing was a success!
If you’re looking for the Absolute Best, Certified Way to Do Pair Programming™, Aidan and I won’t tell you we found the perfect answer. In fact, if we knew the answer, we’d probably keep it a secret and charge big tech companies exorbitant consulting fees for access to our knowledge. That being said, we’re reasonably confident you can have success with pair programming if you give it a try with our initial five questions in mind. Don’t just randomly start a Zoom call with Jamie Echlin and demand that he help you with your code (I mean, he probably would, but still). Have a plan, keep an open mind, and just do it. If you’re anything like me, you might be surprised to find out that you don’t actually hate pair programming