Just Teach It

Mon 23 June 2014 by psu

I have never liked the term term computer literacy. This phrase was coined in the early 80s right around the time the first consumer computers became available. Then, as now, there was a lot of anxiety around the machines. Then, as now, people weren't quite sure what to make of them. Then, as now, relatively few people had figured out how they really worked. Educators started throwing the idea of computer literacy around as a new requirement for students, so that they could be prepared for the future, and all that. Then, as now, it was all bullshit.

What I didn't like about the phrase when I was 16 was that it seemed to me ludicrous to declare that before some arbitrary threshold of competence you were "illiterate" with computers and beyond that imaginary line suddenly you were "literate". Where did this line live, and when did you cross it? Did you cross it when you figured out how to turn the machine on? Format a floppy disk? Write a simple BASIC program to draw a sine wave?

My 16 year old self didn't know too much, but I was perceptive enough to understand that there is no arbitrary line, and that everyone interacts with the machines at their own level. Of course, I was not perceptive enough to not look down my nose at the people who were "too stupid" to understand the machines as well as me. Me and my arrogant punk friends would sneer at these people and call them "users". Oh well, all high school kids are really the same.

These days the lines have shifted around a bit but the angst is still there. These days the imperative is to teach everyone "to code".

Angry Digression Number One: Let's get one thing straight. As far as I'm concerned, in the context of computer programming, the word code is a fucking noun, and always singular. You do not "code", you write code. You are not a "coder". You are a programmer. Programmers write code. They do not write "codes". Scientists with a rudimentary understanding of FORTRAN write "codes". But they are made out of code. And that code mostly does things like simulate the weather. Everything that is interpreted, compiled, and otherwise executed in the stored memory of a computer system is code. C code, Pascal Code, Haskell Code, assembly language code, machine code, microcode. It's always code. I realize I'm too late to this and that the fight is over, but I just have to say it once.


As before with computer literacy it's not really clear that anyone truly understands what it means to teach people "to code" (note, that's the last time I'm going to write that phrase). Activities that might count in this context include:

  1. Writing a web page at one of the hosting services, and changing the CSS so that the background is blue.

  2. Copying and pasting some simple Javascript or Python examples from a web site and watching them execute in your browser, or on your computer.

  3. Finishing an introductory programming class at a major technical university, like the one I went to.

  4. Getting a Bachelors or Masters degree in Computer Science and/or Software Engineering, finding a cushy job at Google or Apple and becoming one of the bus-riding douche-bags in SF (you gotta dream big)

It is this confusion that makes articles about this subject so infuriating. They start with the motivation:

Some people get rich programming computers!

Or maybe

If you can program computers, then you can make cool shit like video games, or the special effects for IRON MAN 6!

They move on to the problem statement:

But there is a terrible shortage of people who know how to program computers!

Finally, the proposed solution is always the same:

TEACH MOAR CODE

Soon enough though, you run into a problem. The problem is that, as I have written before, computers are really stupid machines, and telling them how to do things is tedious, time consuming, error-prone, and requires a strange state of mind that is somewhere between autism and chronic self-hatred. Most kids who start out with "I will program the next Angry Birds!" end up with "What exactly does 'segmentation fault' mean anyway?", give up, and take up something a bit more rewarding, like repeatedly bashing your forehead into a two-by-four until you can feel your face start to cave in.

Anyway, in general

TEACH MOAR CODE

becomes

CODE TOO HARD

I mean, let's face it, we're a nation that is convinced that basic algebra is beyond the cognitive abilities of a large percentage of its children, is there really any hope that they would be able to learn to program computers?

At this point the discussion will shift away from actually teaching anyone to program computers and move on to teaching them other things about computers that are not quite so punishing. This mostly falls into the area of finding and using specialized applications for solving certain kinds of problems: how to create presentations for really boring talks, how to run the payroll, how to lie with statistics, and so on. The idea is to use higher level and friendlier problems to motivate the kids into learning how computers operate. Instead of staring at

Segmentation fault - (core dumped)

Instead you get a friendly dialog box with a bomb in it (say).

I actually think that this is on the right track. As I have written in the past, people need concrete experience on which to hang higher abstract thinking. They have a lot of trouble chasing the abstraction ghosts (which is why so many kids hate algebra: "just what is x anyway??"). Therefore, let the record show that I am all for teaching high level programming first, and then moving on to the harder stuff at the advanced levels. That's how I got into the game (BASIC, then Pascal, then C and Unix) and I see no reason why the path can't work for other people.

However, there are two ways where this thinking tends to go wrong.

  1. People convince themselves that the high level summary is sufficient to actually teach anyone to program a computer, or even understand how a computer works at a high level.

  2. People convince themselves that the right way to go is to always use the computer stuff in the service of some other more interesting application, which is the real goal.

This is the thinking that I cannot abide, and this is exactly the bait-and-switch that occurs in this article from Mother Jones which is what triggered my anger in the first place. Speaking of anger.

Angry Digression Number Two: I've had it with the patronizing idea that Computer Science can't stand alone as an academic discipline. Instead we are constantly told that the key to getting the kids interested is to use the "application of computers to your real interest" as the wedge. I say this is crap. I say that the theoretical and practical problems associated with programming computers is as rich and deep a field of intellectual investigation as anything that we have discovered in the last two centuries. There is almost no end of interesting problems to be solved, and while it is flattering people in all those other areas want to get into our game, we should not kid ourselves into thinking that it is necessary.

Even this phrase "computational thinking" has the air of declaring that "computation" is a second class citizen. Here you go, they are saying, use your wondrous intellectual powers to come up with a grand new idea, and then the slave programmers can do the gut-work of turning it into code (it's a noun!) for you. Nothing pisses me off more than the idea that once the high level specification of a system is done then the rest will just fall out as a "simple matter of programming", as if a robot could do it. I will not have this. Programming computers is one of the most intellectually fulfilling activities that a human being can engage in. While it can be a tedious slog, it can also be filled with unimaginable creativity. So stop it with this "simple matter of programming" bullshit.


The Mother Jones piece starts with "there aren't enough programmers" and makes the full arc through "but computer science is hard" to "so really we should teach them 'computational thinking'" to finally declaring that they have achieved victory by developing a computer science course for high school students that doesn't even make them touch a computer. Instead of all that terrible computer programming they learn about running restaurants, or city planning, or nutrition. Oh the joy.

On the one hand, I'll say that I think this is the wrong approach. And it is also annoying that the piece never circles back on exactly what this new curriculum does to jump from these warm and fuzzy high level discussions to the actual work for making new programmers. On the other hand, I will say that the proposal is similar to one made by no less a Computer Science Luminary than Edsger W. Dijkstra. In one of this papers, called "On the cruelty of really teaching computing science", he proposed teaching the entire Freshman introduction to Computer Science as nothing but an abstract math course: an exercise in formal systems.

Digression Number Three, Not really Angry This Time: I thought this was nuts in 1988 and I still think it's nuts now. But then I'm just a guy, not a noted Computer Science Luminary. So you can decide who to believe. I will note though that he shares my distaste for "all soft sciences for which computing now acts as some sort of interdisciplinary haven". So there.

Here is why Dijkstra is wrong. I actually already wrote down the reason above:

People need concrete experience on which to hang higher order abstract thinking.

In other words, to understand computer systems as an exercise in formal logic, you need some experience manipulating computer systems. You have to experience the wonder and the pain of figuring out how to tell these infernally stupid machines how to do the simplest things. Only then can you understand why Dijkstra wants to torture you with predicate calculus, type theory, loop invariants and pre- and post- conditions. He is perfectly right that people need to learn these things. But I've never thought that starting there was the right idea, and no one will ever convince me otherwise. That's like teaching algebra before understanding arithmetic and geometry.


The rest of the Mother Jones piece meanders around in a weird narrative that combines bad cooking analogies with even worse analogies to the traditional kind of literacy. They also toss in ad hominem attacks on the AP CS curriculum (probably justified), Java (maybe justified), and the institutional racism and sexism inherent in the current educational system (also probably justified). I found the juxtaposition of critiquing technical education with angry hippy politics to be a bit strange. But that's a subject for a different rant.

The constant allusions to cooking and restaurants did made me wonder if these people might want to rework professional culinary training in the same way that they propose to rework how we teach people computer programming. I've heard that cooking school is really hard work and very frustrating. Maybe we should be teaching "culinary thinking" instead of the harder things like knife technique and how to survive on a sauté line. You could just imagine what a nice restaurant might be like, but not actually have to engage in any of the messy business of running one. What you would get if you did this with a bunch of people who think they understand how restaurant cooking works, but have no real experience with it. They would be useless.

Can you imagine applying this idea to other fields? What if sports teams did this kind of soft training instead of actually practicing mechanics and strategy? What if, because practicing an instrument is so much work we instead taught "musical thinking" and expected to get better musicians this way. That would be ludicrous.

Similarly, this idea of pushing "computational thinking" is off base. It will perhaps have the positive effect of teaching some non-programmers to think a bit more systematically, but it will not achieve the stated goal: it won't create any programmers. At least not if you don't keep going.

In my view you learn real computational thinking most effectively by doing one thing: telling computers to do things and having them fail repeatedly until you do it right. In other words, you learn it by programming computers. So my point is, just teach that.

You don't have to start with writing code into a blank Emacs buffer. Start them with the high level stuff. Find interesting problems that they want to solve on the computer and push them to solve them. But at some point it has to go further. You need to get them into an environment where they are required to take the basic tools (data structures, algorithms, abstraction, system design) and learn to use them to bend the machine to their will. This leap is a hard one for people to make. It might be harder than the one from arithmetic to algebra. You will risk losing more than a few to apathy or just plain frustration. But the ones who follow you through will be hooked and will have gained the ability to engage that special kind of brain damage which is necessary to continue to work with the machines. If your goal is to increase the population of programmers in the world, these are the kids you want. These are the ones who will be able to build your blue-sky systems for you, or your software to implement social change, or cool city-planning apps.

But there are no shortcuts, and the good ones are hard to find and probably hard to teach. But I have to believe that the end result is worth it.

Category: Computers