#spa2010 reflections 2: Three hours to teach (and learn) a new language

One of the pleasures of SPA is the coverage of new and interesting ideas in programming languages. This reflects its origins as the conference of the BCS Object Oriented Programming and Systems specialist group - OOPS - although as the history of the group relates, a focus on teams and organisations coupled with a commitment to reflective practice has been there from the start. But how do you get across the flavour of a new language in a short period of time? SPA workshops are commonly three hours long, which doesn’t seem much to be able to both outline what’s special about a language and (crucially) to give people hands-on experience of working with it.

This year at SPA I went to sessions on Clojure (which was new to me, though I’m familiar (or was (at least some years ago)) with Lisp), Scala (I read the book and had a play when it was new, so this was something of a refresher) and Haskell (one day, I’ll find a problem I need to solve in Haskell and learn it properly). All interesting, all different, but all made me think not about the languages themselves, but about how best to teach and learn them in the workshop setting.

The sessions on Scala and Clojure were informative, but ultimately frustrating. They ended up being too much talk and not enough doing, mostly down to the presenters’ anxiety to answer specific questions (has to be tempered with keeping things moving for the rest of the group), but also because the sessions didn’t seem to be designed to build knowledge through practice — perhaps, though, too much time on talk meant we didn’t get to the planned lab sessions. The Haskell session focussed on one aspect of the language (lazy evaluation), and was more successful, even though (oddly) it was the least interactive: a first half demonstrated with several code extracts how laziness worked in Haskell, moving from simple to complex: I think I learned more of the operational model in that hour than I’d picked up from any amount of reading before. A second half of live coding worked through an example (solving a mastermind puzzle) step-by-step, more or less a masterclass in thinking in Haskell. Maybe given the mind-shifts that most of us need to make with Haskell this was the best way.

In 2007 Peter Marks and I ran a session called Serious JavaScript — in which we proposed JavaScript as a powerful and flexible language that could be turned to numerous purposes other than browser scripting (with V8 and tools such as node.js it’s good to see it escaping from the browser environment). The session had two parts - firstly a series of conversations, then a lab session we called explorations. The conversations featured what we called ‘an interview with the interpreter” — Peter talked and asked questions, I typed in response (we used Rhino and the Rhino shell, along with Scite with fonts set really big):


Can I print a number?
    js> 42
    42

add two numbers?
    js> 1 + 2.5
    3.5
(all numbers are floating point)

what about 1 + 2 * 3?
    js> 1 + 2 * 3
    7
(operator precedence works as expected)

Division by 0?
   js> 1 / 0
   Infinity

What do strings look like?
    js> 'Hello JavaScript'
    Hello JavaScript

Can we concatenate strings?
   js> 'Goodbye ' + "World"
   Goodbye World
(single and double quotes can be used)

String and number?
   js> "All for " + 1
   All for 1
(operators overload)

And so on, through basic types, arrays, objects, control, functions and methods. If this looks familiar, that’s because it isn’t original: we borrowed the structure from The Little Lisper, Daniel Friedman’s wonderful book on the basics of Lisp (now in its fourth edition, as The Little Schemer):

LittleSchemer Example

We interspersed these with four short exercises for the participants: files of code for pairs to play with covering the ideas introduced in the previous conversation: here’s the beginning of the first one:


//---------------------------------- 1
x = 1;
print(x);
// What will this print?
quit();

//---------------------------------- 2
//w;
//print (w);
// What will this print?
// Why is this commented out?
// (Hint - try uncommenting it ... )
quit();

//---------------------------------- 3
var y;
print (y);
// What will this print?
quit();

//---------------------------------- 4
print (yy);
var yy;
// What will this print?
quit();

//---------------------------------- 5
y = 1;
print (y);
// What will this print?
quit();

// . . .

For each point, pairs were to look at the code, try to predict what would happen, try it out, see if their prediction was correct, try to understand what happened if it was not, then comment out the quit() call to move on to the next. Doing this, we covered fundamentals very quickly, setting us up for the second half of the session, where pairs could choose one or more explorations, ranging from the simple (exploring lists and functional abstraction) to the complex (implementing classes and aspects) to the insane (yes, monads!). Here’s one of the simpler explorations:


/*

Using closures to implement objects
=================================
(Grade - easy)

1) Can you write a function called account which
    - takes a single parameter called b
    - returns a function (let's call it M) of no arguments
      which returns the value b

2) Now change the function M so that it
    - takes a single parameter
    - updates b by adding the parameter
    - returns the new b

Is this a little like objects? Yes!

3) Change account so that it returns an object with a single
method called deposit that is exactly the same as M in 2 above, but
doesn't return anything. Add another method called withdraw that
deducts its parameter from b. Add another called balance that returns b.

Congratulations! You've implemented an object programming model! Note
that it enforces encapsulation, which JavaScript's object model does not.

What is the downside of this model?

*/

From our own experience of this session, and from the feedback, we think this is a good way to introduce language ideas. Some key points for us:

  • Like everything else, running this session is more fun in pairs. Find someone who’s as keen as you on the language to work with
  • Say a few words about why the language is interesting or important, and give a brief outline of its history, before you start
  • People need to use the language in such sessions. Syntax on slides and lots of talk doesn’t cut it. The sooner they’re trying things out, the better
  • Start simple, and demonstrate what’s familiar before tackling more individualistic aspects of a language (but feel free to throw in a ‘taster’ or two of the more powerful features to get people curious)
  • Keep things moving. In the exposition of the language ideas, it’s important not to get sidetracked by the one or two members of the group (there will always be some) who ask challenging or interesting questions. No-one will mind if you say “let’s cover that later” or “we might not get to that, but try it out in the practical”
  • Syntax on slides is generally not a great way of getting things across. Show code in an editor or interpreter, then run it.
  • Preparation, preparation, preparation. Rehearse the coding (I’ve seen presenters surprised by things not happening as expected in a live coding session)
  • A simple copy or one-click install for the environment and materials for the practical sessions is important. Make sure you have versions for the common environments you’ll find on peoples’ machines (OS X, Windows, probably Ubuntu amongst the linuxes), and make sure you’ve trialled the installation and practicals in these environments

No Comments

Add your own comment...