April 25, 2020

Remote First, Pair Programming and Emacs

At my work, we are advocates of pair programming. From an organisational perspective, the practice has several advantages. We're often more productive working with someone else -- we keep each other on task and get stuck less often and for shorter periods of time. More importantly, the resulting code is generally better and more robust, in my experience, especially when combined with test- or behaviour-driven development.

Businesses often object to the practice based on cost. Why pay two programmers to do the work of one? But at the end of the day, you'll have two developers intimately familiar with the code for future modifications and maintenance -- i.e., the bulk of the software's lifespan. Yes, you spend more in the short term, but for a better payoff in the future. You're investing in the team, spreading the knowledge more widely.

We've had to make some modifications to the practice, because our team hasn't been co-located for some time. The lockdown has just reinforced those practices. Rather than sitting at the same workstation, passing the keyboard back and forth, we pair remotely in various different ways.

Git Ping Pong

My favourite approach, even when sat next to a colleague, is to ping-pong the work through a shared repository (such as Github). One of us writes a test, which fails, and commits the code. The other, checks out the code and makes the test pass. For a bigger refactoring, I'll try to use the pomodoro technique. Each of us types for 25 minutes and then commits the work-in-progress. We take a break between sessions.

One big advantage of the ping-pong approach is that both of you must be set up to work on the code -- at a minimum, be able to compile and run the tests. Getting to that point is often a big hurdle with complex software. If you can get two programmers to that stage, you've again increased the robustness and resilience of the team as a whole. Also, at any given time, our work-in-progress is committed and available, making it easier to do things like mix up pairs, do interim code reviews or pursue experimental paths with the confidence of having a known good state behind us.

Generally, I try to make sure that the person who is "driving" the work isn't the same as the person typing. So, for example, I'll be telling the person what test to write, and they will be telling me how to get the test to pass. This keeps us both fully engaged. But usually, once we really get going, the roles blur and we mind-meld into a single programmer with twice the brain power. It's quite magical when you hit that stride!

Editor Wars

As an Emacs user -- and the sole Emacs user on my team -- I face a couple of unique challenges. My pair for the day will often be intimidated by the spartan interface and unfamiliar keyboard shortcuts. There is one Vim user among my colleagues, but most use either IntelliJ IDEA or VS Code. The VS Code users will also sometimes use the Live Share feature, which I agree is a nice way to share a session.

This can be a source of friction. Two programmers each using their own editor doesn't fit the traditional definition of pair programming, and people do get quite heated on this point of doctrine. Why bother if you don't do it "right", they ask? Some programmers also can't understand why I won't just use IntelliJ or VS Code. To them, I'm being pig-headed or stubborn, but I feel as crippled in those editors as they probably do in Emacs or Vim.

Emacs has a couple of other disadvantages for pairing remotely, as well. It doesn't show line numbers by default, for example. You can't easily point to a section of code verbally ("Now, change line 23 so that it uses the variable on line 6"). I also like to have as much of my code on the screen at once. I turn off all the menus and other distractions and set the font size a bit low. That's not as nice an experience for my remote partner.

Visual Niceties

To make the experience of working with me as pleasant as possible, I've recently tweaked my configuration. I have added a couple of items to my top-level menu (bound to Ctrl-z) to let me turn line numbers on and off and adjust the font size globally. Neither involved writing any new code -- the functionality was already in Emacs. Here's how I set up my main menu, for which I use the hydra package:

 (kbd "C-z")
 (defhydra hydra-global-menu (:color red :hint nil)
^Display^        ^Buffers^                    ^Actions^
_g_: zoom-in     _d_: close all buffers       _u_: update all packages
_s_: zoom-out    _o_: open buffer on desktop  _l_: display line numbers

_q_: quit this menu                         _r_: restart emacs
   ("g" default-text-scale-increase)
   ("s" default-text-scale-decrease)
   ("d" kill-all-buffers)
   ("l" global-display-line-numbers-mode)
   ("r" stop-and-restart-emacs)
   ("u" eds-straight-pull-or-prune)
   ("o" eds/open-buffer-on-desktop)
   ("q" nil)))

The above makes a colour-coded menu appear at the bottom of my screen whenever I type C-z. The first two items (zoom-in and zoom-out) and the one to display line numbers were added specifically for remote working. I can quickly set up a font size that works for both of us and turn on line numbers with just a couple of keystrokes. I've also been experimenting with different themes, to make the contrast better and easier to read on a small screen over a remote link. My current is Leuven. For the pomodoro technique, I use pomidor, which displays a nice, big colour coded history of the time we've spent in each session.

If you're interested in some of the other items in that menu, my whole configuration is on Github.

Reducing Friction

I'm not going to convince any of my colleagues to pick up Emacs -- I've long ago given up on religious wars -- but we can meet in the middle, both of us using the environment and editor that makes us as productive as possible.

In the end, the aim is to get to that mind-meld stage -- getting into the flow. Anything that reduces the friction helps. If we're both comfortable in our working environment, can see and talk to each other easily and can view each other's screens, we're well on our way.

Tags: remote-first emacs