Collaborative programming

Intro
This is a guide with a set of recommendations for collaborative programming sessions and learnings that addresses all engineers, contributors, and volunteers who write code or are learning how to code and are interested in working more collaboratively. As anyone that is contributing to the work of the Wikimedia Foundation it can be inspiring to go back to our values regularly and think: what does this mean for the way we work together on a daily basis? Thinking about more collaborative ways to write code this one stands out:

We are in this together. Collaboration is not always easy. Sometimes we struggle. Working together is hard, but it’s worth it. We do it because it makes us stronger. We solve problems better together. For it to work well, each of us needs to be honest, accountable, and transparent to one another.

Definitely one has to experience a good pair programming session to get convinced of doing it repeatedly. It's actually a little bit hard to get into because you might feel vulnerable and exposed to everyone's observation, but soon after there is a point where that openness to show the way you work allows you to build trust within the team because we realise that nobody knows it all and everyone has to look things up and think stuff through properly. The huge advantage of a pairing session is that "we are in this together" and the others can help you think and research. What if getting into a more collaborative way to write code actually solves problems in a way that addresses the lack of diversity and leads to less bug-prone code?

What problem is this trying to solve?
Knowledge about our codebase can easily get siloed so that some of the codebase doesn't get maintained as much as it deserves and is hard to understand is not being handed over when people move around and focus on other work. That's nobody's fault and just in the nature of moving talent, but we can actively work against it by continuously sharing knowledge. There are so many ways to share knowledge i.e. written docs, workshops, and collaborative programming sessions being one of them.

If we are touching parts of the codebase unknown to us we sometimes don't know who to talk to and it would be nice to know which teams to go to for specific questions. Especially with a growing number of developers, it doesn't seem worth the effort of sifting through a list of people who could be knowing about the feature you currently touching or implementing or the technology you want to learn about and it seems to be easier to work alone. Potentially multiple people are struggling through the same issue repeatedly or in parallel because they are not aware of who they could learn from and share experiences with.

In addition to that, all teams seem to have their deadlines to hit and there's no time or space for collaboration or learning sessions. Collaboration seems to slow the progress on our own work down.

Terminology
Isn't that all the same: Pair Programming, Mob Programming, and Collaborative Programming? Yes, it's pretty much all the same while Mob Programming allows more joiners that contribute to a session. We decided to use Collaborative Programming as a more general term that includes all of the other ones.

Other Benefits

 * it can lead to more diverse teams and groups where people really feel welcome, where knowledge is being actively shared and where developers want to stay
 * a bigger variety of opinions in the process of code creation leads to a wider range of problems being solved
 * improvement of developer experience
 * studies show small team velocities seem to have gone up
 * quality of code can be improved
 * sense of belonging in teams
 * improved knowledge sharing

While some of us have experienced collaborative programming as a beneficial approach there are actually various studies backing this:

Collaborative Programming Session Sample Structure
Here is a suggested setup for a collaborative programming session. If all of this seems too rigid, skip the recommendations, and do your own thing: meet and show each other your code and talk through it, what matters is that you collaborate in the process.
 * 1) There are no rules, there is only a set of recommendations.
 * 2) It’s not a requirement to join the session that one knows the codebase or a specific language because you will be working as a team (a group of two to five people) who meets for a call.
 * 3) One person is always leading the session for a while and sharing their screen and is implementing one small step of a problem that the group wants to solve together, let's call that person the writer.
 * 4) One other team member is the "researcher" that asks curious questions and suggests things to try and implement that could be one step of a solution.
 * 5) If you have a nice pair programming tool setup that’s great, so different people can be active, otherwise the one that shows their code, the writer, can be following the instructions of the researcher
 * 6) What's most important is that the researcher role is being handed over every 10-15 mins.
 * 7) Being the writer make sure you describe what you are trying to do while you write and as an observer make sure you stay engaged and ask questions about things you are unsure about.
 * 8) At any point, people can ask questions and ask for help from the team for looks up things in the docs ask for ideas about what to do next.
 * 9) As the researcher, if there are people in the team that have less experience than you make sure you keep them included by asking little questions: "What should we do next?" or "How can we solve this?"

Collaborative Programming Tips

 * Clarity in the goal: have a clear agenda "we are fixing this bug" or "we are adding this feature"
 * Clarity in the context: What project/files/classes are being involved in the exercise? Sometimes moving from one file to another can cause confusion to the researcher, so it's good to have the whole working space in mind.
 * Clarity in the process: How do we test things to see that they are working? Do we run phpunit? How do we debug, how do we track the errors?
 * Clarity in the authorship: When pushing code, we are pushing from a particular Gerrit user. It's impossible to have both names as authors of the code, but the commit message can have information about those who have contributed to this. Mostly if this is external contributors and volunteers.
 * Additional advice: Be mindful! if this is a session between WMF staff and external contributor, attribution is a way to engage and thank the volunteer.

How to communicate during a session?
As opposed to a workshop the goal of a pairing session is not to present a solution or a technology to your team, but rather to get to a solution together. Therefore specific communication rules apply:
 * refrain from saying things like "obviously" or "simply", because what you are implementing seems simple to you, but rather approach your teammates with empathy, and assume that you have different knowledge of different parts of the codebase
 * when somebody has a question we pause and answer as good as we possibly can
 * rather overcommunicate and talk the others through what you are trying to do
 * when you realise the other one did a mistake, do not interrupt but bring up your concerns when they have finished their point
 * use always only non-judgemental language, saying "you did it wrong" might not be the best way to make your pairs aware of a mistake, rather say: "have you considered..."
 * be careful about strong opinions, sometimes a strong opinion is justified, but more often is just a way to ignore other possible ways that are also okay
 * have a dialogue as opposed to a discussion where one has to "win" and come to a resolution together
 * do not be afraid to change your opinion, adaptability, and change of opinions are a sign of an intelligent collaborator

What's a good way to initiate collaborative programming sessions?
They can be either ad-hoc or be scheduled sessions a few times a week to make sure you reserve time for it. Some teams do that and call them Collab sessions, for example the Platform Engineering Team and the Community Tech Team. If you would be interested in having sessions with your teammates there are several options:
 * 1) Don't hesitate to ask them directly
 * 2) Ask your Engineering Manager or Tech Lead to plan a session for you with someone from another team that's up for it
 * 3) Some teams have Code Jams, something like an internal hackathon, feel free to suggest one for your team.
 * 4) You have a big task that you are handing over to another developer to be reviewed, that can be a great moment to offer a session to give them a rough overview of files changed and how they belong together.
 * 5) You are working on a part of the codebase that you really enjoy working with and would love to share your knowledge. Publicly announce that you are open to collaboration!  (Note: This is different than giving a workshop.)

Great moments to start can be:

 * your team found a small enough bug that you think could be fixed in an hour or two
 * you are working on a feature that has a lot of impact and affects lots of people and want to make sure you do the right thing
 * you feel stuck for more than a few hours and want to talk through your solution with someone
 * you don't feel ready to design the solution of a ticket and would like some inspiration from your teammates
 * you are working on something and feel like that other teams could have some really valuable knowledge that would help you proceed/begin
 * you are completely sure about how to implement a ticket but it would be interesting to see if others agree

How to facilitate a collaborative programming session?

 * 1) Ask around for some developers that are curious about it.
 * 2) Find a non-urgent bug that you think could be progressed in an hour or two.
 * 3) Setup a call, with people in similar time zones. (if timezones are too spread out provide multiple sessions for your team)
 * 4) All jump into the call and ask tons of curious questions.

A change of mindset about the way we work together can help:
The point of having a collaborative session is not that you will all be more effective together, the point is to collaborate and learn from each other and get more conscious of anti-patterns and with a bit of practise you will actually write better code.

"Try treating programming as a learning activity that throws off running code as a byproduct" ~@KentBeck

Recommended Tools

 * one tool that has a lot of potential is https://duckly.com/ because it's working with different editors.
 * Extension for Intellij https://plugins.jetbrains.com/plugin/14225-codetogether
 * Extension for Visual Studio Code https://docs.microsoft.com/en-us/visualstudio/liveshare/use/vscode
 * just sharing your screen with an editor open can be completely fine, as long as you reassign the researcher
 * timer for sessions http://mobster.cc/ to help ensure that the researcher is randomly being reassigned

Acknowledgements
Throughout the creation of this guide, various people have contributed extensively with feedback, comments, and ideas, provided important input, and added sections that are truly important for the guide, this is a living document, and additions or edits are welcome. Important contributions came from Nikki Nikkhoui, Daniel Kinzler and Genoveva Galarza Heredero. Thank you all!