Recently I've been exploring extreme programming, a concept I was introduced to by college students, and was recently reminded of by some comments on a slashdot post. Today I would like to propose a pair programming utility to help apply the concept of pair programming to a distributed working team, such as those which drive most Open Source Software.
Pair programming is a simple concept. Instead of taking up a piece of code and working on it yourself, you code while another person watches you code and tells you what to do from time to time. In this way, code is reviewed for bugs as it is written; and isolated problems are solved by two minds instead of one. For simplicity, the person typing at the keyboard is known as the driver, while the person watching is known as the navigator.
I recognize pair programming as a more robust implementation of what I do when I code. When I write code, I think about the problem first. As I solve the problem, I write code, reviewing each line as I go and making sure it's doing what I want. I review each block too, where a block is an arbitrary set of code that performs one small function. Once I'm done writing a function, I review the entire function and make sure I didn't screw it up.
Unfortunately, this has limits. While I produce few bugs—one in 50 LOC is easy for me, one in 5000 is highly unrealistic—the bugs I do produce are highly obscure and difficult to locate. This isn't inherant; the code is not obscure, but the problems don't indicate exactly what line of code the bugs are on. As a result, I have to review my own code. This leads to a psychological blindness issue: if I thought it was right when I wrote it, I'll think it's right when I review it.
Pair programming introduces peer review instead of self review. As the driver writes his code, he still thinks about it as normal and notices when something seems blatantly wrong; however, there's now a second programmer watching his code. This produces twice the review on the spot, allowing the navigator to make code suggestions and bug fixes on the fly.
Review by another programmer is higher in quality than self review. Things the driver normally holds a psychological blind spot to are very clear to the other. This is because a person may have an affinity to a small misthought which creates a repeatable mistake. These conditions are isolated in the person's mind; finding someone else's bugs is much easier than finding your own.
The navigator can also make coding and design suggestions to the driver. Rather than having one programmer alternate between typing and thinking, the navigator can continue to think while the driver types. The navigator and driver can both think at the same time, both working on the same problem. Overall, the efficiency of the two programmers is increased beyond one.
With pair programming, the navigator and programmer are both intimately close to the code and involved in close communication. This means that two people who understand what they are working with are able to converse freely. Problem solving occurs more rapidly, because they can discuss developing designs as they think of them, allowing two programmers to concurrently work on and improve a design. Because of this, poor but workable designs are more easily replaced with good designs.
Pair programming also places two programmers on the same code base and the same job at the same time. Because of this, both the navigator and the driver gain a deep understanding of the code and the design for that task. This leaves more than one programmer understanding the program; and by pairing up with different people on various parts of code, knowledge and understanding spreads. Such pairs should of course involve at least one person whose navigated or driven the code before.
In a nutshell, pair programming increases the quality and efficiency of your programming team, increasing their effectiveness at solving problems and desseminating knowledge through them. Pair programming also increases the quality of code, reducing the number of bugs in the finished product.
It has been assessed that the trade-off is well worth it. A pair programming team operates at approximately 85% of the speed of two programmers; however, the team, when functioning properly, produces bugs with only 85% the frequency of individual programmers, according to a study at a Utah university. Locating bugs takes excessive analysis and re-reading of program code, and thus bugs are a great deal more expensive than initial programming time, usually by orders of magnitude.
Unfortunately, in the Open Source community, most programmers are geographically isolated. Pair programming is not an option currently, and its efficiency cannot be harnessed. There are no tools to facilitate pair programming either, although such tools may be possible.
The most important part to remember in designing such tools is that pair programming involves isolated access to programming resources. The programmers share one keyboard and one monitor; terminal sharing programs which allow concurrent access, such as VNC, are inappropriate for this task. They also do not allow fluid communication between programmers.
The most appropriate solution would be a communications, terminal, and text library to aid in the adaptation of existing tools into pair programming. Such a library would need to be able to control who could modify the document in progress; send events between clients to communicate modifications in realtime; and allow a communications pipe between applications.
As this would mostly be used for text, the text delta encoding would likely be best handled as a position-operation pair, such as
position=1934,operation=insert:6:"hello;". A command language would be more useful for realtime, however. Such a command stream would be seen as bellow:
POS 1934 // Go to position 1934 INS h // insert h INS e INS l INS O BSP // backspace INS l INS o INS ; POS 1003 DEL // delete the next character, shifting the rest back END // end stream
In practice, the above stream would likely condense each instruction into a single byte. For example,
POS could be 0x01,
INS could be 0x02 followed by the byte to insert, and so on. Programs like vi would need their own encoding language to be more efficient.
The encoded stream could be huffman compressed as well, which would encode the repetitive instructions into two to three bit representations. Huffman produces output for each set of input that encodes to over a byte, so the stream could automatically flush (END) if a byte wasn't produced in 500mS. Supplying H323v2 Speex encoded voice for an easily available communications pipe may be a good idea as well.
Pair programming increases the efficiency and quality of both a programming team and the code they produce. An Open Source library can be created to allow Open Source Software to easily create a pair programming environment. Such a library would help to allow OSS developers to explore the venues of pair programming and possibly create software quickly and more efficiently.