Rethinking Programming Language Tutorials

Imagine you've never programmed before, and the first language you're learning is Lua. Why not start with the official book about Lua? Not too far in you run across this paragraph:

The table type implements associative arrays. An associative array is an array that can be indexed not only with numbers, but also with strings or any other value of the language, except nil. Moreover, tables have no fixed size; you can add as many elements as you want to a table dynamically. Tables are the main (in fact, the only) data structuring mechanism in Lua, and a powerful one. We use tables to represent ordinary arrays, symbol tables, sets, records, queues, and other data structures, in a simple, uniform, and efficient way. Lua uses tables to represent packages as well. When we write io.read, we mean "the read entry from the io package". For Lua, that means "index the table io using the string "read" as the key".

All right, where to start with this? "Associative arrays"? The topic at hand is tables, and they're defined as being synonymous with an odd term that's almost certainly unfamiliar. Ah, okay, "associative array" is defined in the next sentence, but it goes off track quickly. "Indexed" gets casually used; there's the assumption that the reader understands about arrays and indexing. Then there's the curious addendum of "except nil." All this talk of arrays and association and indexing, and the novice's head is surely swimming, and then the author throws in that little clarification, "except nil," as if that's the question sure to be on the mind of someone who has just learned of the existence of something called a table.

I've only dissected two sentences of that paragraph so far.

Really, I should stop, but I can't resist the declaration "Lua uses tables to represent packages as well." Who is that sentence written for exactly? It has no bearing on what a table is or how to use one; it's a five mile high view showing that a beautifully invisible language feature--packages--is really not so invisible and instead relies on this table idea which hasn't been explained yet.

I don't mean to single out Lua here. I can easily find tutorials for other languages that have the same problems. Every Haskell tutorial trots out laziness and folding and type systems far too early and abstractly. Why? Because those are the concerns of people who write Haskell tutorials.

To really learn to program, you have to go around in circles and absorb a lot of information. You need to get immersed in the terminology. You'll be exposed to the foibles and obsessions of language communities. You'll absorb beliefs that were previously absorbed by people who went on to write programming tutorials. It's hard to come out of the process without being transformed. Not only will you have learned to program, but all that nonsense that you struggled with ("We use tables to represent ordinary arrays...") no longer matters, because you get it. After that point it's difficult to see the madness, but it's still there.

Programming language tutorials shouldn't be about learning languages. They should be about something interesting, and you learn the language in the process.

If you want to learn to play guitar, the wrong approach is to pick up a book about music theory and a chart showing where all the notes are on the fretboard. There's a huge gap between knowing all that stuff and actually playing songs. That's why good music lessons involve playing recognizable songs throughout the process. But what do we get in programming tutorials? Hello World. Fibonacci sequences. Much important manipulation of "foo."

Not all tutorials are this way. Paradigms of Artificial Intelligence Programming is a survey of classic AI programs mixed together with enough details about Lisp to understand them. I've mentioned others in Five Memorable Books About Programming. But I still want to see more. "Image Processing in Lua." "Massively Multiplayer Games in Erlang." "Exploring Music Theory (using Python)."

I'll give a real example of how "Image Processing in Lua" could work. You can convert the RGB values of a pixel to a monochrome intensity value by multiplying Red, Green, and Blue by 0.3, 0.6, and 0.1 respectively, and summing the results. That's an easily understandable Lua function:

function intensity(r, g, b) return r*0.3 + g*0.6 + b*0.1 end

If each color value ranges from 0 to 255, then a full white pixel should return the maximum intensity:

intensity(255, 255, 255)

and it does: 255. This tiny program opens the door for showing how the R, G, and B values can be grouped together into a single thing...and that turns out to be a table! There's also the opportunity to show that each color element can be named, instead of remembering a fixed order:

{green=255, blue=255, red=255}

Rewriting the "intensity" function first using tables and then using tables with named elements should hammer home what a table is and how it gets used. There was no need to mention any techy tangentials, like "tables have no fixed size." (That can go in a terse reference doc.)

After all, the reason to learn a programming language is to do something useful with it, not simply to know the language.

(If you liked this, you might like The World's Most Mind-Bending Language Has the Best Development Environment.)

permalink April 3, 2010

previously