The Benefits of Pair Programming
My first exposure to pair programming wasn't great. While there were some clear benefits, the practice was enforced to an creativity-killing level. My second exposure was more positive. I joined a company that did pair programming organically (sorry, I'm not sure how they got to that point, I realize that would be useful information).
There are some obvious benefits to pair programming when talking about it in context of mentoring, on-boarding or problem solving. But my experience tells me that the impact can be more fundamental. Briefly it comes down to continuous improvement via exposure to different perspective.
Most of our commonly used engineering practices are focused on the end product. Tests, monitoring and code reviews all, in their own way, look at code in its [near] final stage. They focus on what was built. Depending on the sharpness of the code reviewer and his or her familiarity with the system, you'll hopefully get some insight into how. But, very few technique looks at how you got there. And that's an important thing to optimize because how you reached a solution doesn't only speak about efficiency but also quality.
I was trying to think of analogies, and the first that came to mind was about becoming a better painter (weird, I don't paint). I thought about the difference between improving oneself from looking at a painting vs watching Bob Ross apply his craft.
While I like this analogy, I think it's applicable to virtually all work (and certainly true for all crafts, which programming, in its current shape, most certainly is): to improve, looking at how you do something is at least as important as looking at the final result.
Pair programming can be abrasive. Most of us like to solve problems the way we like to solve problems. To make things worse, we tend to prefer doing our problem solving in isolation. Having someone make suggestions for what's normally a private activity, takes some getting used to. There are other ways you can improve, but I don't know any that are as immediate and concrete as pair programming. The back and forth you have with your pair isn't theoretical, it's applicable here and now to actual code.
What kind of improvements am I talking about? It can be anything, from mechanical things about how you use your tools (shortcuts, plugins, ...) to more abstract benefits like how to attack a problem.
As a slightly more concrete example, I know a lot of developers who always develop a feature by starting from the public API. They don't think about their data structures or data access patterns until much later (or maybe it's security, or performance, or....). Sometimes that's fine, but other times, it can lead to wasted effort and even a sub-optimal solution (which is still likely to pass a code review). I tend to look at things from the other end. By pair programming, we not only reduce the chance that we'll waste time, we also both get exposed to a new perspective to use or things to consider when solving problems.
There's plenty of room for me to improve how I program. There's also plenty of ways to achieve those improvements. But working closely with someone while actually programming, exposes me to different ideas and ways of thinking to a degree that is very hard to get in isolation.