Great article. I've never done a formal two weeks pair programming exercise like this. Like most, I've been involved in hours or even day long exercises where the goal is to solve a specific and troublesome problem, but never for regular day to day work.
How about the ergonomics though? Seems like it would be hard for both people to get a comfortable position in front of the monitor for that long. Seems like it would be ok for a couple of hours but longer than that I've always leveraged a projector type setup
We've got quite large desk and good quality screen. So we just zoomed in on font size and that was ok. I would not do it on a projector as after few hours on a projector eyes tend to don't see anything any more.
I've never done pair programming in a professional setting, but every time I've paired on a personal project it's been really awesome. Then again, my pairs were great coders, so I can't comment on what would happen if your pair was terrible.
I guess it works for training new engineers -- they can learn from each other as well as from experienced folks. After a while though, the outcome will be that one either has the talent and the 'knack' for it, or they don't. Those with talent and skill will outgrow the need for training wheels and structured support.
What you call "the talent and the 'knack' for it" is simply acquired skill. Anyone willing to put in the hours of deliberate practice will get the skill. There is no inborn 'knack', except simple stuff such as being taller helps basketball.
So, anyone who sings (deliberately trying, I'll grant you) for long enough will be a great singer. Anyone who swings a golf club long enough will be a great golfer. Simply trying hard at something for a long time leads to greatness.....I completely disagree.
Talent is a word with meaning that is separate and apart from experience.
Witness, I ask you, the legion of mediocre talent that fill the halls of Corporate IT. Many of those folks did just fine in their Comp. Sci. programs. However, the talent to create and devise is not achieved by 'practice'. For many -- the curiosity fades and it becomes a 'job'. (For those, the pairing idea might actually help a lot, by the way)
When an individual has _both_ talent and experience, they're worth something. With only one, they're not.
A very common misconception. There's an active scientific field, sociology of performance, that studies exactly this, how excellence is made, and they have simply concluded that talent equals experience.
"So, anyone who sings (deliberately trying, I'll grant you) for long enough will be a great singer. Anyone who swings a golf club long enough will be a great golfer."
Yup, that's it, as long as it's deliberate practice - which is not just practicing deliberately.
Have you worked w/ TDD? I have not, but am considering it or a variant (some gray mushy middle). If you've worked w/ TDD but don't like it, what are your thoughts on this article which dicusses research on TDD:
The problem with most research supporting the use of TDD is that it compares TDD with a base line of no unit testing at all, without controlling for adding unit tests either first or last but without the test-driven aspects.
There seems to be a fairly strong case for adopting unit tests in typical commercial development processes, and some interesting debate regarding whether it is more effective by various metrics to write the tests before or after the development, but there isn't much evidence that I've seen for going the extra way to a fully test-driven process.
Yes, I have used it in two projects myself and been involved in another project where I added a few features. If you are working on a straight forward CRUD web app that does not interface with other services there is some value. One project in which I was involved and 5+ interfaces with other surfaces. Maintaining all of the mocks became very expensive. At one point it was determined that maybe half of the development time became devoted to test case maintinance. Eventually it was decided to abandon unit tests and just do integration testing. Another project was more xmpp based. I started with TDD but eventual gave up because the architure was in flux. All the experimentation put a great expense in test case maintenance. I also ditched unit tests for integration testing. You have to decide how much effort you are willing to put in test maintenance. If the expense is to greate scale back to something affordable.
I think managers for agile teams should be forced to "pair program" too every single day, with a forced partner rotation scheme. Then we'll see how long pair programming would survive.
In the correct setting where one in the pair really needs help it's very useful. The equivalent of grabbing a team member and say "I need some input here, will you take a look at this code/problem?". Like it was long before "Agile".
But to be forced into pair programming with forced rotation scheme every single day year after year is nothing but torture.
"Pair programming" is probably the only agile practice of which I am not convinced. I'm open to do it, but I don't really know how much productive you become. Also a lot of people seem to think agile is equivalent to "pair programming" and reject the rest of the practices.
I really think it's one of those harder things to quantify. I've seen a very low amount of defects in code that I've written in a pair; how many bugs would have been in there without the pair? How much time would it have taken to fix those bugs? How serious would they have been?
Preventative measures are always harder to quantify.
I think what programming (or more accurately hacking) really needs is a better way for programmers to communicate while coding.
Easier sharing, collaborating, communicating, etc. Message boards, email lists, irc channels, instant messages, etc simply don't cut it anymore and never really were that effective at anything other than starting fights and pissing people off.
Maybe I can provide some insight, since I'm seeing a lot of "I've never tried pairing but I bet it sucks" kind of comments:
I've been pairing for about two years now with a broad array of partners-- I came to work for a startup whose policy is "all pairing, all the time" for any code that goes into production. I was pretty leery of the practice initially. What I've discovered is that pairing is just like anything else: it depends completely on the people involved.
There is no faster way to get bootstrapped on a new technology or codebase. Period. This is not a junior dev/inexperienced coder argument; finding all the holes and tweaks in a new library or package takes time regardless of how good you are-- if you're pairing with someone who knows the new tech (in my case, it was RSpec) you're getting constant guidance, tips, and corrections.
Pairing can help stop you from putting stupidity in the code. Many, many times I've been called out for trying to take a shortcut, skipping or forgetting a test, or just making a dumb mistake. It's a little appalling how many brain-dead dumb mistakes programmers make (Yes, that includes you. It doubly includes you if your first reaction was "I hardly ever make mistakes!").
Code quality is worlds better. Programmers tend to pick the first solution they like and implement it; pairing forces you to justify that decision.
Focus is much, much higher. When solo progging (for side work or personal projects) I've noticed I tend to defocus when I hit a hard problem I need to think about. This is the danger zone where I may click over to my email or twitter feed "for just a second" while I'm chewing on a problem.
You back out of dead-ends a lot faster. Getting stuck looking up some arbitrary or incomprehensible behavior in a library is far less frequent and painful when you've got two people working on it (one of whom may already know how/why something is happening).
There are a number of other benefits that you can find in any discussion of pairing, the above are the big benefits that stand out to me.
That said, there are a couple people pairing will not work for:
Mr. "This will never work." Self-fulfilling prophecy, enough said.
Complete incompetents: these are rarer that you might think, but you just can't drag someone along in a pairing situation. Before long they'll be surfing fark.com while you do the work.
Bulldozers: Some folks just pick a "solution" and will implement, fight for, and force that solution at all costs, no matter how bad it is.
The Lazy: Fights tend to crop up when one person wants to do something the right way, and the pair partner's argument is basically "But that's a lot of work!" This is where you usually see disagreements crop up about "over-engineering" vs. "sloppy code."
In short, pair programming can be a wonderful practice that produces super-high-quality code in a fraction of the time. It takes dedication and effort from both partners. I think a lot of programmers fear it because they worry they'll be outed or labeled as incompetents or slugs-- it pays to remember, though that the point of pairing is not to engage in a mutual junk-kicking, but to finish work, improve the code, and improve both programmers all at the same time.
In my experience this is true when you're solving easy problems. The hard part of solving lots of easy problems includes managing time, not making errors, creating simple, understandable abstractions, etc.
Solving well lots of easy problems in a consistent, manageable way is itself a hard problem, to which pair programming is imho a great solution.
I've come to the conclusion that for individual hard problems, where you're trying to understand how to implement a complicated algorithm or some such, individual programming allows a much better attention span. It's hard to get "in the zone" pair programming. In this case, I prefer "asynchronous pair programming" (joke), by which I mean code review and asking colleagues for advice.
Does "In the Zone" programming actually provide quality and no-bug benefits comparable to pair programming? I suppose you could suggest that you would follow it up with a code review, but when you sum all the reviewing process to the coding process, does an organization end up spending more time coding/reviewing/fixing this portion of the codebase after either technique?
I've never done development pairing. But I did a project once where I acted as the developer and my partner was a subject matter expert.
He would define a set of requirements, I'd code them up and iterate releases every day or so. He'd use it for a day and either while using it, or after gathering up some notes, give me the next round of requirements.
Our release cycles were measured in hours not days and we went from prototype to working-in-a-production-environment in a month.
The technology we built in those three months was either bug free or all the known errata were well documented, we had manuals, well commented code, design documents, methods and operation manuals, and real world working results. It replaced a major component written a couple of years prior by a team of three developers with a faster, more robust, more portable, more extensible piece of code that coupled more tightly to the subject matter requirements while still being flexible enough for other domains. It was ported to Java by a major systems integrator for use as a critical infrastructure link between components on a $150mil/year contract and some of the components and lessons from it became important pieces in a number of other pieces of software and solutions. Another port was made for a web deployable data processing engine on another multi-million dollar contract.
It was without a doubt the most prolific, most rewarding and most productive project I've ever been on bar none and I'm convinced that it was the extremely fast cycle time from requirements to working code that did it.
Along the way, what we discovered is that the fast iterations quickly made us realize that requirements we thought were important initially weren't, and new important ones emerged quickly. If we had tried to set requirements and build monolithically, we would have produced code no better than the previous code because the requirements going in weren't really all that much different than what went into the original program.
While I agree with much of the article, one note I find important from my pair programming exercises is that pointing out typos is nit-picking and slows the whole process down. It interrupts the flow of the programmer and doesn't contribute anything useful, since the compiler will point out all typos in due time. (All things in moderation: if it's the sort of typo the compiler won't catch and will cause unexpected behavior, then point it out by all means).
This sort of mentality is important to consider on higher levels as well. We need to find what actually improves the development process and focus on doing those things while at the same time refraining from doing things that slow down the process.
23 comments
[ 4.4 ms ] story [ 57.4 ms ] threadHow about the ergonomics though? Seems like it would be hard for both people to get a comfortable position in front of the monitor for that long. Seems like it would be ok for a couple of hours but longer than that I've always leveraged a projector type setup
Talent is a word with meaning that is separate and apart from experience.
Witness, I ask you, the legion of mediocre talent that fill the halls of Corporate IT. Many of those folks did just fine in their Comp. Sci. programs. However, the talent to create and devise is not achieved by 'practice'. For many -- the curiosity fades and it becomes a 'job'. (For those, the pairing idea might actually help a lot, by the way)
When an individual has _both_ talent and experience, they're worth something. With only one, they're not.
I recommend "The mundanity of excellence" by Chambliss. Here's a scribd link: http://www.scribd.com/doc/2926754/The-Mundanity-of-Excellenc...
Yup, that's it, as long as it's deliberate practice - which is not just practicing deliberately.I would add:
Often employed at consultancies where it allows them to charge twice the rate for half the productivity
http://blog.objectmentor.com/articles/2009/10/07/tdd-derange...
There seems to be a fairly strong case for adopting unit tests in typical commercial development processes, and some interesting debate regarding whether it is more effective by various metrics to write the tests before or after the development, but there isn't much evidence that I've seen for going the extra way to a fully test-driven process.
In the correct setting where one in the pair really needs help it's very useful. The equivalent of grabbing a team member and say "I need some input here, will you take a look at this code/problem?". Like it was long before "Agile".
But to be forced into pair programming with forced rotation scheme every single day year after year is nothing but torture.
Preventative measures are always harder to quantify.
Easier sharing, collaborating, communicating, etc. Message boards, email lists, irc channels, instant messages, etc simply don't cut it anymore and never really were that effective at anything other than starting fights and pissing people off.
I've been pairing for about two years now with a broad array of partners-- I came to work for a startup whose policy is "all pairing, all the time" for any code that goes into production. I was pretty leery of the practice initially. What I've discovered is that pairing is just like anything else: it depends completely on the people involved.
There is no faster way to get bootstrapped on a new technology or codebase. Period. This is not a junior dev/inexperienced coder argument; finding all the holes and tweaks in a new library or package takes time regardless of how good you are-- if you're pairing with someone who knows the new tech (in my case, it was RSpec) you're getting constant guidance, tips, and corrections.
Pairing can help stop you from putting stupidity in the code. Many, many times I've been called out for trying to take a shortcut, skipping or forgetting a test, or just making a dumb mistake. It's a little appalling how many brain-dead dumb mistakes programmers make (Yes, that includes you. It doubly includes you if your first reaction was "I hardly ever make mistakes!").
Code quality is worlds better. Programmers tend to pick the first solution they like and implement it; pairing forces you to justify that decision.
Focus is much, much higher. When solo progging (for side work or personal projects) I've noticed I tend to defocus when I hit a hard problem I need to think about. This is the danger zone where I may click over to my email or twitter feed "for just a second" while I'm chewing on a problem.
You back out of dead-ends a lot faster. Getting stuck looking up some arbitrary or incomprehensible behavior in a library is far less frequent and painful when you've got two people working on it (one of whom may already know how/why something is happening).
There are a number of other benefits that you can find in any discussion of pairing, the above are the big benefits that stand out to me.
That said, there are a couple people pairing will not work for:
Mr. "This will never work." Self-fulfilling prophecy, enough said.
Complete incompetents: these are rarer that you might think, but you just can't drag someone along in a pairing situation. Before long they'll be surfing fark.com while you do the work.
Bulldozers: Some folks just pick a "solution" and will implement, fight for, and force that solution at all costs, no matter how bad it is.
The Lazy: Fights tend to crop up when one person wants to do something the right way, and the pair partner's argument is basically "But that's a lot of work!" This is where you usually see disagreements crop up about "over-engineering" vs. "sloppy code."
In short, pair programming can be a wonderful practice that produces super-high-quality code in a fraction of the time. It takes dedication and effort from both partners. I think a lot of programmers fear it because they worry they'll be outed or labeled as incompetents or slugs-- it pays to remember, though that the point of pairing is not to engage in a mutual junk-kicking, but to finish work, improve the code, and improve both programmers all at the same time.
Solving well lots of easy problems in a consistent, manageable way is itself a hard problem, to which pair programming is imho a great solution.
I've come to the conclusion that for individual hard problems, where you're trying to understand how to implement a complicated algorithm or some such, individual programming allows a much better attention span. It's hard to get "in the zone" pair programming. In this case, I prefer "asynchronous pair programming" (joke), by which I mean code review and asking colleagues for advice.
He would define a set of requirements, I'd code them up and iterate releases every day or so. He'd use it for a day and either while using it, or after gathering up some notes, give me the next round of requirements.
Our release cycles were measured in hours not days and we went from prototype to working-in-a-production-environment in a month.
The technology we built in those three months was either bug free or all the known errata were well documented, we had manuals, well commented code, design documents, methods and operation manuals, and real world working results. It replaced a major component written a couple of years prior by a team of three developers with a faster, more robust, more portable, more extensible piece of code that coupled more tightly to the subject matter requirements while still being flexible enough for other domains. It was ported to Java by a major systems integrator for use as a critical infrastructure link between components on a $150mil/year contract and some of the components and lessons from it became important pieces in a number of other pieces of software and solutions. Another port was made for a web deployable data processing engine on another multi-million dollar contract.
It was without a doubt the most prolific, most rewarding and most productive project I've ever been on bar none and I'm convinced that it was the extremely fast cycle time from requirements to working code that did it.
Along the way, what we discovered is that the fast iterations quickly made us realize that requirements we thought were important initially weren't, and new important ones emerged quickly. If we had tried to set requirements and build monolithically, we would have produced code no better than the previous code because the requirements going in weren't really all that much different than what went into the original program.
This sort of mentality is important to consider on higher levels as well. We need to find what actually improves the development process and focus on doing those things while at the same time refraining from doing things that slow down the process.