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.

For many developers with a background in Ruby or Python (or other similarly human-readable languages), the switch to Objective-C can be overwhelming because of the differences in syntax. Objective-C code tends to include non-alphanumeric characters, which are confusing to read if you’re not used to seeing them in your code. I’ll go through a few them here, to act as a small Rosetta Stone (Pebble?) as you start reading + writing Objective-C.

@ – The @ sign is frequently found as a prefix to keywords (@implementation, @interface, @protocol, @end) that are used for defining classes. It’s a direction for the compiler – but as a programmer, it indicates to you where the implementation of your class (or its interface, or protocol) begins and ends.

The @ sign is also found in front of numbers, strings, arrays, and dictionaries. It’s shorthand for creating these objects – consider the snippet below:

This verbose syntax is an older way of writing Objective-C. It’s still valid, but the @ sign allows us to simplify it considerably to the snippet below. In this case, the @ sign is also a compiler directive.

If you want to learn more about the @ sign, the Clang (Objective-C compiler) documentation has technical details. Additionally, Mattt Thompson has a great blog post which goes into some of the more obscure uses of the @ sign.

* – The asterisk is literally ALL over the place. An asterisk before a variable definition indicates that the variable is a pointer to an object. For example, let’s consider the first line of code above:

NSString *foo = [NSString stringWithUTF8String:"Hello World!"];

We’re defining foo as a pointer to an object of type NSString. Most variables you define in Objective-C will be pointers. Exceptions to this rule include int, float, other basic scalar types, and anything whose underlying implementation is a struct (ie, CGRect).

When you want to send a message to an object, you do not need to prefix the variable that points to it with an asterisk. Let’s say we want an uppercase “Hello World!” string – we do this by calling [foo uppercaseString], not [*foo uppercaseString].

& – The ampersand is the ying to the asterisk’s yang. It returns the address that a variable points to, which is the address at which the object is actually stored. The expression &foo might evaluate to 0x1a815f0. Consider the snippet below:

NSLog(@"%p", &foo); //logs 0x1a815f0, the address to which foo points
NSLog(@"%p", foo); //logs the address that foo itself is stored at

Ampersands are often used to pass around errors. In the code snippet below, the method on NSString modifies our error for us, but does not return a new error.

You probably won’t see as many ampersands as you will asterisks, but it’s helpful to know what they mean. If you see a method definition with a parameter whose type includes **, that’s an indication to pass in the address of the object, rather than the pointer to the object.

# – The pound/hash sign is called a pragma in Objective-C. Like the @ sign, it’s a compiler directive. XCode also understand them, so you’ll frequently see them used for file organization. You’ll frequently see them followed by the words “pragma mark – …”, like below: