 I guess it's about time. Can you all hear me? I can hear myself. But OK, cool. Great. Awesome. So let's get started. This talk is called Pairing, A Guide for Fruitful Collaboration, Strawberry Peach Pair. I just saw on my way in. They didn't get the emoji onto the sign, and I'm so upset. I did hear that I managed to break the proposal website by submitting a talk with emoji in the title, though. So I've got that going for me. So back to pairing. This is kind of like an evergreen programming conversational topic. You talk to devs. The devs that you talk to are like, pairing is great. Devs are like, oh, I tried pairing. It was kind of actually horrible. There's a broad spectrum of response to pairing. Some devs have a great experience pairing with peers where everyone's on the same page, and they all have about the same amount of knowledge. And then you go pair with someone who's fresh out of bootcamp, and you're kind of like, I don't know how to. And another really common pairing situation is sitting down with someone who is already super familiar with something that you're not as familiar with, and then you start working together. And five minutes later, you realize that you're just going to be stuck here for however many hours this session lasts, watching, and not quite understanding what's happening while they do things. And so this talk is really about how to get to the point where you can watch for that and keep it from happening in both directions. Making something pairing something that you can not only do with any other dev, like kind of regardless of relative experience level, but that you can even maybe want to do with any other dev because it's like a useful, valuable thing to spend time doing. So let's talk about how to make pairing a kind of like more flexible, useful, valuable tool in your programming toolbox. Real quick, as we dive in, I'm Andre Arco. I'm indirect on the internet things. I co-authored the third edition of the Ruby Way, which is a cool book about Ruby. I founded Ruby Together, the nonprofit that helps fund development work on Bundler and Ruby Gems. It's kind of cool. It's like the first thing to ever model this, where devs and companies give money to a nonprofit, and the nonprofit gives money to people who build open source. And then everyone gets better open source. Pretty cool. I've also been the lead developer of Bundler since about 2012. And thank you. And then for my day job, because open source does not pay San Francisco rents, I am a consultant at Cloud City. And I do architecture stuff. And actually for about five years, my day job as a consultant has been to join engineering teams and work with them on architecture decisions and just like day to day sitting down and pairing with the team that's already there, basically all day long every day. So a lot of the stuff that I'm going to talk about is kind of like pulled directly from mistakes that I have made over the last five years. And now you cannot make those mistakes. So that's, well, ideally. We'll see how it goes. So even if you're already convinced that pairing is good, which is kind of like a thing that seems to swirl around in the zeitgeist of the Ruby community, pairing is good. That doesn't come with a definition or instructions. So what is pairing? Even if you've already been convinced that pairing is good, you don't have instructions. And if you ask 10 different developers, what is pairing, they will give you 10 completely almost entirely non-overlapping answers, probably, in my experience. So for this talk, we're going to start with kind of the simplest possible thing and build up from there. It's like working with another developer on a single machine. You don't like one computer, even if you have two screens and two keyboards and two mice, you're both working together on the same machine. And so if you've never had a good pairing experience, this is probably the point where you're like, why would you force two developers to only have one machine? This is just going to be one developer sitting around bored and one developer working, and that sounds horrible. Happily, in a good pairing session, that is not how things turn out. So let's look at how that's possible. Ultimately, the thing that programming is doing is not about typing and making code appear. It's about solving problems. And a thing that pairing does when you are working together with someone else is usually you are better at solving problems than you are when you're working by yourself. It is totally normal for multiple human beings to work together to produce a single solution to a problem. Like this is not controversial. People have meetings. People have brainstorming sessions. People talk things out, get feedback from other people. I guess as worshiped as the idea of pair programming can sometimes be, it's honestly, in some very real senses, it's just a very small meeting where you're coming up with good solutions to your programming problems. And so pairing is about bringing that kind of collaborative experience where you're positively working together with people to the day-to-day work of programming. And I totally admit, meetings can also kind of be a shit show depending on how they're run and depending on who's involved. And so pairing actually shares a lot of the same kind of benefits and disadvantages of two people having a meeting coming up with solutions to problems. So I guess if you've thought about how to make meetings more productive, this is probably going to sound familiar, right? Rather than having one person sit around, while the other person is like, well, what I think we should do is this and that and the other thing, don't you? Good, we're done. Instead, you want to be actively collaborating, communicating, planning, coming up with theories, talking through problems, making suggestions, making sure to get feedback from both sides. Honestly, pairing provides a huge amount, maybe sometimes, even all of the benefits of having code review, but you have effectively instantaneous turnaround time. And you have incredibly high bandwidth communication with the person who's reviewing your code because you're both sitting there talking to one another rather than writing cryptic five-word comments at one another every 12 hours until the end of time. And having another person talking through the problem with you is a great way to notice that you've fallen down a rabbit hole and now suddenly you're actually way over there, even though the problem that you're theoretically solving is over here. Rotating back and forth, who is actually pushing the buttons, is a great way to kind of like stave off fatigue, kind of like get a little bit of a perspective reset as you're like, oh, OK, now I'm going to see how things are kind of like one step back from I'm actually pushing the buttons and the letters are appearing. And taking turns doing that is, again, like a very productivity enhancing thing in the sense of like we're trying to solve this problem, even if it's not productivity enhancing in the sense of, well, we pushed less buttons and less code came out. So communicating ideas to your pair means that you're kind of like continuously in that, hey, I'm kind of stuck on this. Can I talk it over with you situation, right? You're rubber ducking effectively the whole time. You're explaining your understanding of the problem to someone else. Someone else has the chance to kind of like, oh, have we considered this thing that my experience leads me to believe could be a problem? And so in a kind of ideal pairing situation, what you end up with is the best outcomes of both of you combined, right? Like you are able to preempt the bugs that both of you have seen in the past. And when you have a positive relationship with your pair, you can also, it ends up giving you motivation to kind of like be the best programmer version of yourself, right? When there's someone sitting next to you, you're like, oh, I could just name these variables A, B, and C, and then commit it and then push, and I'd be done. And when there's someone sitting next to you, there can be the like, oh, but that would be confusing and like, I don't want to like make them feel like I'm a crappy programmer. And so with someone else watching, honestly, like it's just harder to justify your bad habits to yourself, which as a person with many like, bad lazy programming habits myself, I can confirm that this like produces much, much better code for the next person to work on it. And since I am usually the next person to work on it, I really appreciate that. So it's not all awesome. Pair programming in kind of like the way that we've talked about how it's like meetings, pair programming comes with all of the problems of meetings and some new problems because programming. And so these are all things that you kind of like need to keep an eye on and make sure, I guess like you need to find ways around them because if they happen, you might as well not be pairing, right? Like you'll come out of the other end and you'll be like, wow, that was a total waste of both of our time. We could have just been working separately. So common problems include, it's very easy for one person to be like, oh, I know how to do this here. Let me, and then an hour later, you're like, oh, cool. Are you ever gonna explain what that thing was? Are we ever gonna talk again or am I just gonna be trapped here watching you program forever? Another problem, you can be pairing with someone who's not interested in being on the same page as you. And if they have very, maybe we can call them ideologically rigid. And if they have opinions and they are not interested in compromise or collaboration with you, it's really not gonna end well. You're just gonna kind of be stuck there forever in an argument that has no real benefit. I demand that we put commas at the end of every trailing, entry in a hash or an array. I don't know. And I guess when pairing with someone more experienced than you, it's also really, really common to feel like you are trapped in a performance review from hell that will never end. Because it's literally your day job to do that. And it lasts, right, like it lasts all day long every day and you're just sitting there sweating, thinking about how soon they will discover that you don't actually know what you're doing and your job will be over. So let's, I guess that pressure creates knock-on problems like, oh, now I'm really nervous, so now I'm panicking and blanking and really worried that even this idea that maybe will work isn't a good enough idea. And so panicking with condescending developers who are kind of like sitting there making it clear that you are not good enough to be pairing with them, can also be like a really frustrating and upsetting situation. And in those kinds of situations, what's happening is the same peer pressure that I was talking about earlier where you're like, oh, you don't wanna cut corners. Well, except now it's the evil version of that where the peer pressure is to like be a bad programmer instead because that's clearly how things work here. So the rest of this talk is to help you get to a point where we can maximize kind of the benefit side of that that I just talked about and minimize the kind of like disadvantages that we just covered. So it's gonna take thought and effort and you probably won't get it right instantly and you probably won't get it right all the time. Honestly, like I still need this list to remind myself how to do a good job after years and years of having done this, it's a skill. And so ultimately all that work can be worth it because pairing can be, when it's done well, one of the most like positive and satisfying ways to experience programming where you've just like done something cool with someone else and now you both feel awesome. So let's talk about the kind of like underlying most basic requirement of pairing with someone which is both people need to actually trust each other enough to be able to cooperate and to work together and to like kind of be interacting in good faith. You can only be one of those people unfortunately. And so if the person that you're trying to pair with is condescending, discouraging, insulting, like talking about how you're not good, that's not like I guess they can do that if they want to, although I really wish they wouldn't, but like that's not a situation that you can successfully pair in. And so if you end up feeling like a burden or like a lesser person while you're pairing with someone, not only is that not your fault, that is the other person completely failing to be a good pair. So let's say you found someone who isn't going to condescend who wants to work with you instead of programming at you while you watch, great. So the rest of the suggestions that I have fall into kind of like three buckets, pairing with peers or people who have about the same amount of experience and familiarity with the subject as you, pairing with people who have less experience than you and pairing with people who have more experience than you. The work that you end up doing has the same goals in all of those situations, but behaviors that can be really helpful in one of those situations can be actively harmful in another one of those situations, like treating someone with less experience like they already know what's going on is just gonna make both of you have a bad time. And in addition, like your pair has to be willing to cooperate with you, share control, share ideas, share credit. So ultimately, if your pair isn't engaging with you in good faith, like this is kind of like the pre-check, like can we work together? And if they're not, like if you feel safe doing it, you can call them out and you can be like, hey, you're just typing and like we're not really pairing or if you don't feel safe doing that, like find someone else to pair with, I'm sorry. Like that's really all you can do. So in the straightforward situation where you're pairing with your peers and you both have about the same amount of experience, this is a really great opportunity to swap tips, kind of like learn the individual things that the person that you're working with has figured out that you have not yet had a chance to figure out or like maybe they've worked in this part of the code base and you've worked in that part of the code base and you can kind of like build a better shared understanding together. You can commiserate about how frustrating it is to try and make this thing work that everyone is frustrated by. And again, generally like the goal is to be trying to produce the combined best results that each of you have to offer. And based on all of the time that I've spent doing this, I am totally convinced that good pairing sessions come down to combining both consent on both sides and communication. If you're staying on the same page, if you're making sure that both of the people who are working together understand what's happening the whole time, you're going to have a much better experience because both of you are going to be able to contribute to whatever it is that you're trying to do. And while working together will take work, the idea is that you'll have better results. So kind of like kicking off from the start this idea of pairing needs consent from both sides. Before you start, like before you literally do anything, what computer are you going to use? What OS are you going to use? What editor are you going to use? What shell are you going to use? Like whose configuration files are you going to use? What shortcuts will make sense? What get aliases are going to be present while you're trying to work together with someone else who has completely different get aliases than you're used to? So if you're going to pair a lot, the ideal is a dedicated pairing station for like one machine per pair of developers all running the same OS, the same Ruby versions, the same editor, the same shell, the same configuration files. And that not only makes it easy to like rotate pairs, like maybe one day you pair with this person and the next day, you know, everyone moves down one. And that's a really great way to kind of like keep everyone sharing a lot of context and understanding about all of the stuff that's happening. But also it means that everyone involved can just kind of like sit down and start working and there's an environment that they already know how to use, right? Like you have a built-in understanding of how to operate the situation. It's not ideal, but in a pinch, you can sit down with someone else's personal machine in that situation. And in my experience, this is not common, but I strongly suggest that you create a completely separate user account just to pair and that it not have all 600 of your get aliases and your 45,000 keyboard shortcuts and your Vim config that no one else understands. And instead, it's something that actually is a shared space between you and the person that you're going to program with. Dropping someone directly into your environment and then telling them that they just have to deal with whatever your shit is really starts things off on the wrong foot if what you're looking for is actually working together with someone. So level the playing field only include things that you have both agreed should be included in the get aliases or the Vim config or the whatever. An extension of this that I've seen when doing remote pairing and the first time I experienced this, it was really a revelation. If you're going to do remote pairing, whoever is typing has to be the person whose screen is being shared. Like you do pairing where you're like screen sharing and one person types and then you're like, okay, now the other person's going to type and that other person has to wait half a second every time they push a letter to see what happened. Like that is a nightmare. Deliberately trade who's hosting the screen share every time you change who's typing and I guess that's like underscores another reason why you want all the machines to be configured the same way because it's a huge pain if you're like switching back and forth in the middle of a pairing session to two completely different configs. But if the person who's typing can always get instantaneous feedback about the buttons that they are pushing, suddenly remote pairing feels basically not any worse than pairing in person. And so like that was a really, like I went from someone who thought that remote pairing was really frustrating to feeling like remote pairing was basically fine and just like any other kind of pairing once it like really hit that whoever is typing needs to have the computer that is sitting in front of them doing the thing. So ready? Don't start typing. So once you have an environment, you're probably all set to just like, yeah, let's go, let's write code totally killing it or whatever. So don't do that. This is one of the moments that totally demonstrates how pairing can be way better than programming by yourself because this is when you and the person that you're working with can actually make sure that you both have the same understanding of the problem that you are about to try and solve by writing code. And so that means that you need to be able to articulate the problem. You both need to come to a shared understanding. You should basically before you're writing code you should be talking back and forth with the person that you're pairing with until you both agree on what the problem is. And that may take a minute, which you're probably not used to if you're used to programming by yourself, but I mean, it may even require reading documentation, checking references, rereading the ticket three times, researching existing code, finding a designer to ask a question like, but you won't have to have spent three hours coding and then realize because of a comment from the designer that what you just built for three hours is not actually the thing that you needed to build. Another perspective is one of the best ways to cover your personal blind spots and vice versa, which is one of the ways that pairing can be super powerful. So reaching shared understanding with another person dramatically reduces the chances that you missed something and you're already building something that is not quite the thing that you actually need. So once you come to an agreement about the problem that you're going to solve, upfront establish guidelines for who is going to be typing and who is going to be thinking and checking the docs and kind of narrating the story of what is happening as you work. So those roles are sometimes called driver and navigator like analogizing to being in a car where there's like a driver and a navigator with the map and whatever. It's not a perfect analogy, but it's a pretty good shorthand to get you to what ideally is happening in the situation. Like one person's responding on the fly to whatever's going on and the other person has a higher level understanding of the situation and is keeping an eye out for that detour coming up ahead and warning you or whatever. It's much easier to notice things, good or bad things when one person is doing the typing and one person is doing the kind of like stepped back thinking about things, checking out the context. So one common approach combines pairing with test-driven development and in that scheme one pair does the driving typing until the current failing test is passing and then adds a new failing test and then you swap driver and navigator roles and the new driver codes until the failing test is passing and then writes a new failing test and then you swap. And I guess there's another approach usually called ping pong programming which one person always writes the tests and one person always writes the implementations, but in that situation it's usually the implementer is trying to write as little code as possible to make the test pass which usually involves lots of like hard coded return statements and I guess it's not, it can get fatiguing and it's maybe not like the best idea to do on like an all day long everyday basis but when I've done it it's been really eye-opening to discover that the tests that I thought were like good thorough tests were actually satisfiable by like five lines of return statements and three ifs. And like the business logic that I thought the tests were testing didn't actually even need to be in the code for the test to pass. So now that you're getting the idea this is a really good time to talk about the biggest problem with pairing which is hey let me do this really quickly myself because I can do it fast. And at the same time that person is always inevitably reaching for the keyboard and mouse even though they theoretically are not the driver and usually what happens after that is 30 to 60 minutes later the person is like yeah I'm sorry this is taking so long I thought it would be really fast. And there's really like you might as well have stopped pairing at that point, right? Like you're not pairing as soon as that happens. So any time this occurs whether you are the person doing it or the person that it is being done to like the pairing is over and there is now an audience and a person who is like programming and showing off to that audience. So instead of that definitely wanna keep both people on the same page and honestly like it's very easy to in kind of like an uneven experience pairing situation the less experienced person will often be like yeah it'd be great if you take over and do this because I feel really uncertain about it and that is still a terrible idea. The payoff of pairing is that you both understand not just what is happening but why it is happening and if the less experienced person who is kind of uncertain about things isn't even getting the chance to like go through the process at the pace that they can like keep up with like there's no reason for them to even be there. Like let them know that that's very flattering of them to say but like don't take control away from them because at that point you might as well just like each get out separate computers and stop pretending that you're pairing. And I very much understand that in this situation you if where you is the like more experienced person the more experienced person might feel very frustrated that something so quote unquote simple is taking so long but this is a really good opportunity to take a deep breath and say this is an opportunity this is a chance for the other person to gain new skills and understanding and context and after this either one of us will be able to do this rather than me being the only person who can do this real quick for the next three hours. And finally both if you're supposedly pairing both of your names are going to go on that code and it's really rude to like hijack the keyboard and mouse do something for an hour and then be like oh yeah and your name is gonna be on this even though you didn't understand anything that happened. Cool. So whichever option you pick for how you're going to coordinate this kind of like transition between driving and navigating it should be clear to both people which person is in which role all the time. Like if you are in a state where you disagree about who is in which role or you're confused about who is in which role back up a little bit and figure it out before you keep going. Trust and collaboration is really hard to sustain when your keyboard and mouse are unexpectedly moving around while you're in the middle of trying to do something. At its most rigid when you're not really comfortable with changing it yet you could even go as far as just like setting a timer and being like we're gonna trade driver and navigator every 10 minutes at its most fluid where like you've got experience pairing with this person and you're super comfortable about it. Maybe it just means that you like say hey can I and the other person's like yeah okay and then but like you know the whole time both of you who is doing the thing even though it's very fluid and moving back and forth every few seconds as is convenient. When you're doing this right another dev should be able to walk up and be like oh hey you're pairing cool who's driving and who's navigating and you should both be able to answer the question without any hesitation and the answers should be the same. So now that we've covered the mechanics of pairing and talked about how to pair with your peers let's talk about how things change when you're pairing with someone more experienced. Pairing with someone more experienced is a great opportunity to talk through ideas hear about new options for solving problems learn about trade offs and kind of see how devs who have spent more time with whatever it is that you're doing than you have have kind of like chosen to adapt to it. The most common pitfall when you're pairing with someone more experienced than you is the feeling that you do not actually have anything to contribute and in fact it is now worse because you are here. It will take work but you can fight that feeling. The person you are pairing with should also be helping you fight that feeling. The person with more experience is the one who's on the hook to make sure that pairing is a cooperative exercise and not just them showing off how awesome of a programmer they are and then leaving with you no better off than you were before you started. When you're pairing with someone more experienced your kind of main job in the pairing situation is to provide feedback. If you hear a concept you're not familiar with ask what it is. If you see something go by too fast to have been sure what that was ask to go by it again. Notice your pair jumping in and doing just that one thing real fast point out that they did that and ask them to back up and take turns. Honestly ask them to help you do the same thing instead because that's why you're pairing isn't it? Just because someone has more experience than you doesn't mean that they're automatically right. Having more experience doesn't mean that they have more experience in every area. I know that when I've paired with devs who I thought knew more than me about everything I have totally discovered that there's like some specific area where I do know something and they're like oh I never knew that before and when pairing with devs who had literally like just started coding within the last few weeks I have regularly discovered that they know all kinds of things that are regularly relevant to whatever it is that we're doing that I had no idea about. The bigger the experience difference is the more important it is for both of you to make sure that your time working together is informative and productive for both of you and not just the supposed cool person. Ask questions, give feedback, work together to calibrate on the speed that you're working at. Work together to calibrate on the depth of what you're working at so that it's maximally beneficial for both of you. You might feel like a burden but trust me like the best part of pairing with someone less experienced is being able to introduce them to new things and have them get it. Like that is by far the best part of pairing with someone who hasn't heard of stuff before. It's all really cool. One more thing to keep in mind with pairing with someone more experienced is that they will probably be able to answer a bunch of kind of like as you're working questions right off the top of their head because they will have run into that problem before and had to look up the answer themselves. And so they'll just remember it. You won't have to go straight to the API docs or Google and try and figure out what the right words are to insert into the Google query to actually get the correct answer. Like people are usually much better at helping you figure out how to phrase your question when you're not sure what your question is in the first place. So I strongly encourage like if you get the chance to pair with someone more experienced than you use that as a resource at kind of like the front of your queue ahead of the docs and ahead of Google or Stack Overflow. And finally, if you run across something that you don't understand, ask about it and maybe they'll tell you the answer, maybe you'll figure out the answer together because they didn't know either. And probably you'll find out that even really experienced people don't know a lot of stuff or really most stuff, honestly. Take advantage of that experience, work together to improve your shared understanding of the concepts and the code and that's really what pairing is all about. Finally, pairing with a dev who is less experienced than yourself is a chance to let them drive and practice and I guess from the other perspective, it's a chance to catch gaps in your own planning. It's a chance to make you better at understanding and communicating ideas. And even though you are more experienced in the thing that you are writing code about, it's still a chance for you to learn and grow and practice your skills of communicating and solving problems, collaboratively. So these are some tactics I've picked up that help when pairing with someone who's less experienced in a kind of positive, cooperative and productive way. Before you start, establish some cooperative, non-judgmental ground rules. You're going to be working together on two goals. One is getting work done but the other goal is deliberately bringing the less experienced developer up to more experienced at an accelerated rate. Make it clear that computers are hard and even though you are more experienced, there are tons of times when you don't know what to do either and if they don't know what to do while you're working together, that is totally not just okay but expected to happen. This is really important if they pause while you're in the middle of doing something. Wait. Even experienced and pretty good in other ways, experienced pair programmers have a tendency to see someone kind of like stop and then be like, oh, the next thing you should do is. And like, that is not actually helpful even though it feels helpful at the time. Instead, wait. And if it's been like 10 seconds maybe, let them know that you're still happy to wait for as long as they would like to try and figure things out but if they want to opt in, you can offer suggestions about what could come next. Make it as hard as possible for yourself to jump in or take over. The let me do this real quicks, like this is a thing that I to this day five years later after doing this basically all day every day, I still have to stop myself and when my self-control is bad, sometimes I can just like grab a fidget toy or grab a giant stuffed animal and hold it instead of typing but when my self-control is really bad, I have to unplug my keyboard so that by the time I am typing, I'm like, oh good, my keyboard was unplugged. I did not just accidentally take over. Good job, pass me. It's very hard to take over by accident when you don't have any input devices so I highly recommend that if it's a problem. And finally, keep in mind that all this work is ultimately a chance for you to level up yourself even though like even when you're working with someone less experienced, it's still a chance for you to be getting better. High-level independent contributor work depends on clear persuasive communication and this is a really good opportunity to practice clear and persuasive communication. Coordinating development work across teams, gaining support for your policy proposals, encouraging developers to adopt good practices. As a senior IC, you can't be a manager who's like, do this or I'll fire you. Instead, you have to be able to actually convince them because you have like a good convincing persuasive thing to say and that is a communication skills problem and this is a chance to practice your communication skills so take it. I'm gonna end with software is made by people and for people and every line of code is the result of some sort of relationship between human beings. Working with a team means planning, communicating, discussing, compromising, debugging and lots of other human interaction things and even though it can be hard to tell when you're up to your eyeballs in code, all programming in the end is a relationship with stakeholders, customers, managers, coworkers, someone and so pair programming is a chance to make that relationship direct and explicit even at the time that you are writing the code with the kind of like trade-off that now all of the benefits and hazards of interpersonal relationships are included with the programming work, that's all I got. It depends a lot, the question was do you have any tips for fostering a pair programming environment at a company and it depends a lot on what you mean by fostering. If you are one junior dev out of 25 devs there is probably not very much that you can do to like change the culture of that team to be more pairing focused. I think honestly mostly fostering a development of pairing means management and senior ICs are on board with the idea that pairing is good and normal and something to do on a daily basis. I don't think that there's a whole lot of adoption that you can drive from the bottom sadly. What's my favorite remote pairing software? Recently I've been using Slack screen sharing and any desk. Honestly like if the person who's supposed to be able to type is always using their own computer almost any screen sharing software is fine, turns out. Cool, thanks so much, we're out of time. If you have any more questions please feel free to let me know on Twitter or the internet and I will try to get back to you. Thanks.