Surviving Chaos with Pairing

I’ve been amiss at my writing for the past year-and-a-half while knee-deep in a startup. I wrote this post somewhere near the end of 2013, but never published it until now. I’ll be adding a follow-on soon. You’ll also have an opportunity to read more about this distributed development experience at PragPub in an upcoming issue.


My Distributed Development Workstation

For the past three months, I’ve been working as part of a startup (minus a few weeks’ worth of other customer engagements). I’ve found myself more often than not working with a new (to me) technology each new day. Here’s a list of some of the new elements:

  • MacOS (my first day-to-day Mac!). Getting used to the keyboard differences, particularly Ctl-Option-Command stuff, has been the most challenging aspect of things, particularly since I’ve still had to switch off to Ubuntu/Windows machines throughout.
  • Ruby. I thought this would be my chance to stop being a Ruby newbie, but we’ve moved on to something better:
  • …Clojure. I’m excited to being picking this up, though it’s my first-day-to-day experience in a functional language. I’m feeling somewhat comfortable with basic language concepts after maybe 6 days of working on it, but of course I’m not anywhere near knowing how to do things the “right” way.
  • Coffeescript. My web UI development experience has always been minimal. It’s kind of weird to be learning Coffeescript with only a shallow foundation in Javascript, thought Coffeescript seems like a nice clean approach (but you still need to peek under the covers at times).
  • Angular, D3, _, and a few other odd Javascript libraries
  • Emacs. Never really wanted to take this on (I prefer vim), but glad I’m learning it. Learning a whole new voluminous set of keymaps is pretty challenging!
  • RubyMine, IntelliJ. It’s been several years since I did any heavy lifting in IntelliJ. Another set of keymaps to remember.
  • Elasticsearch, Sinatra, Jasmine, RSpec, Minitest, numerous other Ruby gems, Nginx, guard, lineman, bootstrap, RabbitMQ, Kafka, Amazon EC2, and maybe a few other small things I’m not remembering. Lots of little tools, none on their own very large an undertaking.

There are a few familiar things, including Jenkins and vim. Altogether, it’s well over 20 new technologies in less than 50 days of work. All this while occasionally bouncing back to Windows, Visual Studio, C#, Fitnesse, and some C++ (to support the release of Modern C++ Programming with Test-Driven Development). I’ve regretfully had to put aside my ramping-up on Android development.

Even more challenging: Most of us work from home.

It’s insane, frustrating, and somehow exhilarating. These are all technologies I’m happy to learn, so it’s all good, but most days I feel fairly stupid. Of course I’m not anywhere near mastering any of the new technologies. Right now, we’re bouncing mostly between Clojure and Coffeescript/Angular, so I hope to master them in due time.

It shouldn’t work, but it does. Why? Everyone on the team is an accomplished programmer. We pair online through most of the day using Google Hangouts, and switch roughly daily (though sometimes every couple days, a bit long for my taste but it helps to have the time to immerse more on the unfamiliar stuff). We communicate frequently through the day via a persistent campfire chat, a morning business briefing, a morning dev planning session, and ad hoc hangouts as needed.

What’s not to like? Well, the pairing constantly sometimes gets old, and we’re pairing a little longer per day than I’d prefer. Bouncing around so frequently between technologies has been rough. And remote communication has its hiccoughs that detract from the experience. Ultimately, nothing is as good as being there.

However, our efforts have been very effective, even with most of the other programmers (about 10) not masters of most of these technologies either (many are intimate with Ruby). We’ve managed to make the customer happy with a quick first effort, and are well into incrementing on a second product.

I can’t imagine attempting something like this without pairing. We’ve had at least one candidate dismiss the opportunity because of pairing–“it can’t possibly be anything but a waste of time to have sharp programmers work together.” But they’re the ones who are missing out–it’s hyper-productive, rewarding, and has been the glue in keeping us from devolving into complete chaos.

Collaborative (Dare I Say Pair?) Writing

I enjoy writing, though I’m not as prolific as I’d like to be. I tend to re-read what I wrote many times, often second-guessing it. Like any writer, I also find difficulty from time-to-time, getting stuck on how to phrase a paragraph or a sentence. I’ll typically mark things and return to them later. All-in-all, I can slam out text, but getting polished product out the door can be challenging.

ball point pen writing

I read and enjoyed Weinberg on Writing: The Fieldstone Method when it came out. I already had been employing its core idea to an extent: capture thoughts as they arise (index cards work great!), then incorporate them as appropriate in an article or book. Each idea on a card might act as a central idea around which writing can build, or it might be used to fill in a “hole” in the text. Emphasizing this technique has made writing a lot more fun, and I tend to not lose great thoughts that had popped into my head.

My best writing experience, however, has been collaborating online with Tim Ottinger, originator and co-author on Agile in a Flash. We had a slow winter–after writing a pile of articles for PragPub, we both got very busy with work, and did little writing. We finally found some time to commit to delivering a new Agile in a Flash post, Is Your Unit Test Isolated?

Two days ago, we got our headsets on, started up a Skype conversation, and talked for a few minutes to agree on what we’d work on. We started some single-threaded editing on a very rough draft at Blogspot, but that wasn’t effective, so I pasted it all into a Google Doc.

Google Docs doesn’t provide the best document editor in the world, but it is highly effective for collaborative writing. You can see each others’ cursor and typing as it occurs, and you can look at offline revisions if necessary for comparison.

Mostly we’re not talking via Skype (and in fact sometimes we’ll collaboratively edit without a voice conversation at all). Instead we’re communicating through the document. Tim will start re-working a paragraph that I might have just finished writing, and I’ll get out of the way. Sometimes I’ll watch and toss in a comment–just typing it right into the document–and other times I’ll go off and stab at a paragraph that Tim wrote. Or I might go off and re-read the document, looking for flow and completeness problems. It’s pretty haphazard, yet it works, and it’s fast. We might go back and forth at a paragraph a few times before we figure it works.

Collaborative writing works best if you grow a layer or two of skin. We’ve learned to be pretty direct: “[[ I don’t like that ]],” Tim might type (the brackets are our way of setting off comments). Ok! Good technical writing requires harsh critique. Better Tim drop a pointed comment than a few thousand readers.

At times I’ll return to find something I’ve written completely gone or gutted and rewritten. It was a little disconcerting at first, but I’ve learned to trust Tim’s reworkings. I can always look at the old revision if I thought an important idea got deleted.

The unit test article took us about an hour to get to 98%. We let a couple outstanding concerns sit for a few hours, made some offline changes, and published it the following morning (yesterday).

As with pair programming, I’ve found such highly collaborative pair-writing to go much faster than writing on my own, and produce a far more effective product.

Abandoning Pairing

For almost a year, I pair programmed on a daily basis as part of a team working for GeoLearning, a small software company that is no more. My enjoyment was tempered by the fact that I was pairing remotely, online with a headset and sometimes a camera, using Skype and WebEx. The contrast to live pairing was marked.

Remote Pairing Cons

  • Lag. Whoever was not hosting the session suffered enough lag to make the experience a bit painful. We didn’t switch enough, probably because of the cost of switching overhead (not only the desktop switching itself, but also getting the source across, which really isn’t all that big a deal with git).
  • Noise. Some people breathe rather heavily, others swallow loudly, and some like to chomp on snacks too much. I did mention it from time to time, but it always felt awkward. And either I was a very good pair, not making these sorts of noises–I doubt it–or others similarly didn’t want to speak up.

Pairing or not, as a remote developer I didn’t feel like I was a real part of the larger, “live” team. I felt that my influence as a remote person was insufficient.

The remote pairing also carried the same issues that “live” pairing can create, most of which are minor. For example, the team had very few standards, which led to some wasteful debates during many of the pairing sessions, still not that big a deal. But couple a lack of standards with stubborn people, and you have a useless pairing session.

I can get along with just about everybody; not the case this time out. I paired with one developer whose concept of TDD was almost completely opposite mine. We produced virtually no useful product during our two or three pairing sessions (we then ended up on different teams, thankfully). In attempts to stop the arguments, I would often say, “Let’s just go with your preferred way of doing things for now.” No such luck. Some folks are simply contrarians.

Remote Pairing Pros

  • It allowed me to stay at home, very welcome after many years of travel, which had created a significant negative impact on my family life.
  • Learning a new system without the ability to lean on someone for several hours a day is tremendously wasteful and frustrating. Remote and isolated, it’s even worse. Pairing rapidly brought me up to speed to the point where I was able to contribute.
  • I could work with the remote pair and not be uncomfortable about things like sitting too close, bad breath, or my laziness on some days when I didn’t feel like showering.
  • The slow cycle times (waiting on compiles, test runs, etc.) were almost bearable due to the fact that you had someone to talk to for the minute or two or more.

Being remote sucks in so many ways–primarily the isolation from the rest of the team–that I wouldn’t have even considered the position had it not been for the ability to pair. I never felt like I was a real part of the larger, “live” team, and I felt that as a remote person I was unable to influence the team much.

So despite the negative aspects of my remote pairing experience, it was the best that I could expect for this opportunity. Ultimately, having this opportunity remotely was better than not having it. And the pairing brought me a small but significant step toward feeling like I was a real part of something.

Pairing No More

I’m currently working a three-month contract for a local firm. It’s a very stable company, there’s no travel on the near horizon, and my commute is about seven minutes door-to-door (it’s three miles away, with only one stoplight inbetween). Those three elements are great, but just about every other element–ranging from pay to preferred way of working to technology–is a concession.

There’s no pairing. My first “real” week (i.e. past most of the HR and setup BS) was spent sitting in an office, digging through a (test-less) codebase, occasionally IMing my teammate a couple offices over to ask questions. It’s a typical no-process environment.

Here’s how I feel about no longer pairing:

  • Bored. Cycle times are again high. I miss having someone to discuss things with during the waits. Checking email, tweets, RSS feeds, and Amazon book ranks helps only a little.
  • Lonely. Stuck in my office with no one to talk to and bounce ideas off, I don’t really feel like I’m part of a team, just one of a number of individuals who happen to work on the same code base and project.
  • Conflicted. I second-guess myself continually. “Is this the company way? Is this the [unfamiliar-to-me technology] way? Does it violate standards? Is it the best design? Did I just do something really stupid? Am I going to get chewed out or look bad for checking this code in?” Unfortunately, second-guessing produces far weaker answers than simply asking someone who already knows and can quickly tell me the answers.
  • Released. One downside of pairing most of the time is it tends to suppress learning by exploration. While I don’t want to work that way all of the time, I’ve found I often learn better when I probe about and try things. With a pair, I usually feel the pressure (even if I’m really the one creating that pressure myself) to move on. And many people who already know the answer tend to simply prefer to tell you it, or more typically grab control and do it themselves rather than wait while you muck around.
    While this may sound damning, it’s easily rectified in a pairing environment: Set a time limit to pairing. I’ve found that a six-hour window is plenty, but it’s up to you and your team to figure out how much works well for you.

Pairing is not for everyone or every team. The bullets above suggest that there are serious challenges both with pairing and with not pairing. But most of the time, I’ve found pairing to be far more enjoyable and productive than not.

Distributed Project Retrospectives

Recently I’ve done three distributed project retrospectives. I’ve heavily used the ideas in the Esther Derby/Diana Larsen book Agile Retrospectives to provide a foundation for these online meetings. Here’s their general flow with a few comments and one addition:

  • Establish base rules They need to “own” the rules but you should expect to kick off with a few of your own.
  • Safety exercise “I am planning on being very open and vocal during this retrospective.” – strongly agree, agree, neutral, disagree, strongly disagree. Answers to this will help you hold at least some people to their promises to talk. It may suggest the need to do even more anonymous polling during the meeting.
  • Gather data For project retrospectives, the Time Line activity has been especially useful. I simply share my desktop, put Excel up and start filling in events, with some dates, from left to right.
  • Generate insights, locate strengths
  • Commit to improvements I solicit as many variant solutions as possible for a given challenge, and then let them vote on what they think the best one is to carry forward on a new project.
  • Close

Here are some brief suppositions and observations:

  • Use “online only.” Everyone on the line should be at a separate station, not meeting together in a room. While this can increase phone line costs, it prevents “phone vs. live” dominance issues. Everyone sees the same thing.
  • Use some sort of communication software with polling capability. I used WebEx for each of these three sessions. It’s flaky but works. Make sure you try creating some questions ahead of time and understand both ends: How are questions defined, and what does the end user see?
  • Some of the problems with WebEx polling:
    • No scaling/ranking question type available
    • Easy to create a screwed-up poll and not know until answers are submitted
    • Crummy interface overall. Too many opportunities for “user error”
    • Can’t easily share anonymous answers to “free form” questions
    • Lame file-based save/load interface
    • I didn’t see how to change the amount of time a poll was open
    • No way to limit the number of “votes” on a multiple-choice answer
  • Come prepared with some good poll questions, but also look to create them on the fly. For example, after soliciting things that went poorly, it’s useful to find out the top three or so to concentrate on. You might normally do this with dot voting and cards. Here, you can create a poll and ask people to select a certain number of items from the list.
  • No matter how hard you try, many people will choose to not talk in a larger (> 15) meeting. With a meeting of ~15 or less, the idea (Derby’s?) of starting the retrospective by asking everyone to express their hopes for the meeting is a very good one; it gets people talking.
  • Get an assistant to take notes, type questions, monitor chat, etc. They will allow you to focus on listening and steering the retrospective.

It’s never the same as everyone being there! I view online retrospectives as a microcosm of doing the whole of agile in a highly distributed fashion. Effective communication becomes very difficult.