Woodshedding: Teaching programming not problem solving
Before I talk about programming, I’d like to put forward a theory: every discipline has its own myths. I’m referring to those beliefs about a discipline’s nature which, though commonly held by its own practitioners, are nonetheless false. I use the word myth to indicate a degree of mysticism, often revealed by a tell tale lack of detail and supporting evidence, peppered with a hint of delusional vanity. Propagating and persisting through a discipline’s pedagogy, myths divert and confuse students’ efforts. For some they create insurmountable challenges, leading lesser pedagogues to conclude that their students ‘either have it or they don’t’ — the ultimate myth.
Let me give you a concrete example. Many years ago I was a student of jazz guitar. A core part of the discipline is improvisation. I remember my teacher, eyes closed in deep concentration, spontaneously producing streams of notes which perfectly twisted their way around the underlying chord sequence of the jazz tune. “How do you do it ?” I would say. “You just gotta hear it,” was his reply. Faithfully following his advice, I listened repeatedly to jazz records with ever more concentration, transcribing and studying the solos of the jazz greats. My transcription became quite good, but my improvisation remained subpar. I hoped that at some point it would all just click, but it didn’t.
The reason why was that my teacher’s response unwittingly belied a common myth about jazz solos; that they are composed entirely in the moment and entirely aurally. In reality improvisation is a little more like talking. There is a degree of spontaneity, but this is hung around one’s esoteric collection of formal devices and phrase fragments — in jazz parlance chops. Chops are developed and internalised through many hours of practice in a process called woodshedding which is as much physical and conceptual as it is aural. So, a regurgitated myth had lead me down a blind alley which seriously hindered my progress. Years later as a music teacher, determined not to lead my own students into the same mistakes, I debunked these myths for them whilst developing exercises for woodshedding.
Well it’s a long story, but fast forward 15 years and I am now a lecturer in Computing at Goldsmiths University. I am lucky enough to lead both the campus and online versions of our core programming course which brings me into contact with around 1300 novice programmers per year. I’ve found the task of ensuring every student’s success a considerable challenge, but I’m not alone in this. The teaching of introductory programming is widely acknowledged as problematic. It’s also no stranger to myths.
The one I’d like to explore here lies around the notion of problem solving as a prerequisite for learning to code. Amongst the pedagogical literature, a lack of problem solving skills is the most cited reason for poor student achievement . In view of this, some advocate the prioritisation of teaching problem solving over developing skills in any particular language. At first sight this all seems quite sensible; if we think of problem solving as abstracting a problem from its context to design a solution, well programming certainly seems to involve a lot of that. So by delaying the considerable challenge of learning a programming language, students can focus on the core skill of problem solving. But, I smell a rat.
A tell tale sign is that definitions around problem solving remain vague and inconsistent. It is not clear how problem solving, algorithmic thinking, computational thinking and abstraction relate to one another, and there is scant discussion or categorisation of students’ difficulties with the topic. More importantly there is the issue of what medium problem solving should be practiced in. Each attempt at extracting problem solving from programming simply yields another pseudocode, whether it be graphical or textual, of poorer design than the programming languages we commonly teach. Furthermore, what is gained through the reduction of the burden of syntax is lost through the eventual need to translate what has been learnt to the domain of code.
The literature correctly identifies problem solving as a central activity of programming, but rather than it being a prerequisite for learning to code, I would argue that things are the other way round. Abstracting problems always requires notation. Programming languages are ideal notations for this task, so it makes sense to use them as the medium to teach it in. I see parallels here with my earlier musical example. There is an idealism at play in both jazz and computing pedagogies which emphasises mind over matter. This, I would suggest, indicates more about practitioners’ regard for their own discipline, than how people learn.
So what should be done for introductory programming ? I advocate that before embarking on any deep engagement with problem solving, students need to build confidence in a suitable computer language. They need to repeatedly practice syntax and patterns to develop an internalised vocabulary which is as much visual and physical as it is conceptual. Does all of this sound familiar ? It should do. Just like jazz improvisers, programmers need to woodshed.