Like so many software engineering techniques, pair programming is a good idea that often gets treated as a religion — and when it becomes a religion, it becomes a bad idea.
The question that doesn’t get asked anywhere near often enough is, “what are we trying to accomplish with pair programming?” If you have a clear answer to that question, you can evaluate whether it makes sense for these people, at this time.
I’ve worked in teams where pair programming was a clear win. Notably, those teams did not try to pair full-time — they did so between 1/10 and 1/3 of the time, when it made sense. It was always done for a reason: because we wanted somebody to come up to speed on a module, or because a problem was thorny and would benefit from multiple eyes on it, or something like that. It wasn’t pre-determined, and didn’t have a quota — by and large, it would be decided in today’s standup that persons A and B would pair today. This would always be voluntary: if either partner is unenthusiastic, it isn’t likely to work.
Pairing as a mechanism for bug reduction is good, but inefficient. On my teams nowadays, I usually accomplish this with mandatory code reviews, and those often accomplish some of the same goals as pairing. The key here is to drain the pejorative tone out of code reviews: it is not that the juniors have to be reviewed by the seniors, it is that everybody’s code gets reviewed by somebody before it gets merged. As Architect, I will most often pull one of the junior engineers in to review my code, and it is my responsibility to explain the code well enough that they understand what I did there, and can explain it back to me. Often, I will catch a bug in my own code in the course of explaining it, or they will catch one (often by asking a question that starts, “but what if?”). It spreads knowledge around, teaches techniques, and (no small thing) gives the junior engineers a boost of confidence when they catch a bug in the senior’s code.
(And yes, it is less powerful than pairing. But it’s easier to justify to management as something you always do, leaving pairing to be used sparingly, when it seems like the right tool.)
And for either mechanism, I believe strongly in mixing up the pairs frequently. One of the major goals of this sort of mechanism is to spread knowledge around, and that works best if you are frequently pairing with different folks. Silo’ing is the great enemy of good code, and there is no better remedy than getting everyone’s hands a little dirty, all over the codebase. Not to mention the social benefit: a team where everyone works with everyone is inevitably a tighter-knit team…