A developer, a teenager and Socrates walk into a bar… they ask questions, and learn from each other. That’s it.
“Rachel, that’s an awful joke!”. True, but it’s not actually a joke! Over the past year, I’ve volunteered through Girls Who Code, co-teaching a class of high school girls about the basics of programming. In doing so, I was reminded of the Socratic method and its usefulness as a teaching tool. Given that one of the goals of pair programming is to transfer knowledge between developers, it makes sense the Socratic method is also an effective tool for teaching and working with other developers. In this post, I’ll outline some of the ways in which it can be useful while pairing.
For context: all the teaching I’ve done this past year has utilized Khan Academy’s programming environment, which provides a constrained subset of the ProcessingJS library. To help the students learn about variables, we introduced them to the draw function, which repeats 60 times per second by default. By incrementing the value of a variable inside this function and then using that variable to dictate the position of a shape in their drawing, students could make it appear that the shape was moving across the screen, like in this animation. One student ended up with an animation looked a lot like the one below, and she asked why the draw function was leaving a trail of old circles.
As someone who’s been programming for a while, I assumed this was a question on syntax, and told her to move the line of code that draws the green background into the draw loop. She seemed perplexed, so I asked her what behavior she expected, and why? It turned out that my assumption was entirely off – as a new programmer, she assumed that every line of code was being repeated, not just the draw loop. Her question, based on how she viewed the world, was really something along the lines of “given that every line of code is supposed to be repeated, why is the green background not getting redrawn after each circle?”
When pairing, most developers won’t prefix their questions with “Given [assumptions about the system], why X?” The best thing to do, before answering a question, is to ask what behavior your pair expects, and why? By questioning your pair, you help to surface assumptions that would have otherwise been implied and not explicitly stated. You might realize that you (or she/he, or both of you) have an incorrect or incomplete idea of how your code works. For example, your pair might know about some quirk of an external API which necessitates a line of seemingly superfluous error checking. With these issues surfaced, it is easier to build a foundation of shared understanding, from which you two can pair more efficiently!
Once I realized that we had different understandings about how the code was executed, I tried to explain to the student that lines of code are executed in order, and that this block of code: var draw = function() { ... }
was just defining a snippet which automagically got executed 60 times per second. Faced with a blank stare by a frustrated teenager, I came up with an analogy that made sense in her frame of reference – a recipe. If all 9 lines of code are a cupcake recipe, then the draw
function is the bit that tells you how to repeatedly decorate each cupcake in the pan.
Because this explanation made sense in the student’s frame of reference, she was able to grasp it quickly and draw some of her own conclusions – for example, the green background is like the frosting applied to each individual cupcake. When pairing, it’s frequently useful to frame explanations and answers in a way that makes the most sense to the questioner’s frame of reference. For example, if your pair has a Rails background and you’re pairing on an iOS project, you might explain [array valueForKeyPath:@"foo.bar.baz"]
as “Look! It’s just like array.map {|obj| obj.foo.bar.baz
!!”
The idea of asking questions in order to answer questions isn’t terribly new; it was in fact popularized more than 2000 years ago by Socrates. However, I believe that the Socratic method is underutilized in pair programming -we frequently focus on whatever problem we’re trying to solve, and expect that knowledge transfer will happen implicitly. By asking questions of our pairs, we can explicitly surface differences in understanding. Doing so helps pairs to facilitate explicit knowledge transfer and to build a stronger shared foundation for approaching a problem – which ultimately leads to a stronger solution.