One of the reasons that pair-programming works so well is the same reason that brainstorming is such a powerful technique in a group setting. Pairing basically amounts to an endless stream of mini-brainstorms between the two partners. I swear that whenever I pair with someone, we’ll write code that is easily three times tighter and cleaner that if I had written it alone, and I think the brainstorming aspect has a lot to do with why.
In formal brainstorming, you start with an initial pool of ideas and build it up by pushing the boundaries, piggy-backing on the previous ideas, and inverting or negating the previous ideas. It’s the job of everyone to be contrariwise with each other — to keep asking “What if?” and “Why not?” In pair programming, a similar thing happens. It’s the job of the person who’s riding shotgun to be looking at the bigger picture (while the one who’s driving is focused more on the task at hand), and this is what makes for the same kind of contrariwise/collaborative atmosphere as brainstorming.