A Thousand Layers of Abstractions
How should we teach programming?
One of Shimon Schocken’s colleagues says that “Computer science is a thousand layers of abstraction.” This is quite true, and the same applies for programming.
Recently I’ve been thinking a lot about how we can get more people involved with programming. I don’t necessarily mean programming as professionals, but just to develop enough of an understanding on what software is and how it works. So I wrote a book aimed at teaching games programming in Python to the 9 to 12 year age range (get ‘em while they’re young). In my “Python is the new BASIC” post, (which was a plug for my free, Creative Commons-licensed book, “Invent Your Own Computer Games with Python”) I received this comment:
You know, I took a look at that game book and it struck me how so 1980s the thing was. It brought me down to memory lane.
Now, looking at the alternative (Squeak), which is fully OOP all the way down to the very menus and icons, buttons, which has a much richer environment and is totally ready for multimedia, along with the derived (written in Squeak) Scratch language, I think it’s very bad that we’re returning to Basic.
Kids deserve something better in 2008, and we can deliver it, just as long as we keep our prejudice at bay against Smalltalk (because it really is about prejudice and lack of information).
1980s would be right. I based the book I wrote on a 1983 book that taught me BASIC programming (adding Python’s modern features). However, my book specifically avoids higher-level concepts such as object-oriented progamming, event-driven applications, and graphics. I thought these concepts would hide the actual underlying workings of the programs. By using textual input and output from simple raw_input() calls and print statements, my book could focus on variables, expressions, and flow control. I wanted as little “magic” as possible.
“Programming is a thousand layers of abstractions.” I’ll argue that to really understand software, one has to go down this rabbit hole all the way to the bottom, as far as assembly or machine language. But one doesn’t need to understand assembly (arguably the lowest of the programming abstraction layers) in order to actually write useful software, even professionally. And for the purpose of teaching programming, those layers of abstractions save us a lot of tedious details. The key to teaching programming is to find that ideal middle ground: low enough to pull back the “automagic” curtain, high enough to stay above minutia.
My book aims low. There are already several high-level game engine SDKs and drag-and-drop game creator packages to make programming easy (well, easier). I would lose the appeal of graphics, animation, and sprites, and instead rely on text and ASCII art. I would use function calls and loops, a level below recursion and callbacks but above dread goto statements. The high-level space already has lots of ink or bytes devoted to it already, so I aimed low.
But maybe I’ve gone too low. I fell back on my target audience (which I pictured as my 9-year-old self). I learned programming from a book that taught games programming in BASIC (which I used as a starting template for IYOCGwP). It covered a lot less ground than my book (the syntax for Python makes complex programming tasks easier). That book had opened up an entirely new creative world for me, which I hope my book will also do. Ask any software developer with motivation that extends beyond a mere paycheck, and they will have a similar “How I Learned to Program” story.
And even though the games in the BASIC book I read were only text, they still held my attention. Console video games of the day (i.e. my 16-bit Super Nintendo) had games that were far more engaging than anything I ever made, but coding my own Tic Tac Toe program still appealed to me. Programming was a fun, creative task. The fruits of my labor were simple, but they were mine.
Is this low approach what we’ve been missing in programming education? Michael Kölling’s Greenfoot and MIT’s Scratch environments have been great successes at general computer science education. Both make liberal use of graphics and automagic techniques that make introducing high-level computer science concepts accessible to the general audience. But I feel that a low enough level of understanding software may be lost in this approach as well.
I’ll be the first to admit, my book’s approach is experimental. I have no trouble confessing that it will probably not appeal to a wide audience of children. But for the neophyte geeks (such as my 9-year-old self), I think a more direct approach gives the young (and not so young) programmer an education that can be applied to a much wider scope of software. Python is both easy to learn, but scales into almost every domain of software development and the professional world.
I’ve been putting some thought into the next book, whose content will be determined by the success (or lack thereof) of this first book. I’m going to keep the teach-by-example format of presenting an entire game’s source code and explaining the principles from the code (unlike teaching principles without immediate and complete application), but I don’t know how high of a step up the abstraction stack I want to take it. I want to introduce graphics, but I don’t know if I will continue with ASCII text with the curses library, or dive into PyGame or Pyglet.
I encourage anyone to take a look at the book (I offer it on http://pythonbook.coffeeghost.net in full for free under a Creative Commons license.) and offer an opinion: how high or low on the abstraction stack should we teach computer programming to those new to the skill? (Especially young folks.) Should we use real languages (like BASIC, Python, Smalltalk, or Java) or languages made specifically for teaching (Scratch, Logo, etc.) Should we have them learn pointers, object-oriented programming, assembly, functional programming, GUIs and/or graphics?
Should we aim high or aim low?


Although your idea appeals to me personally (I learned to program in BASIC on a TRS-80), one of the reasons I was so fascinated with it wasn’t because I could type certain words and make things happen on the screen, but rather that it was very cool.
A nine year old kid knows cool when he sees it, and to him BASIC is no cooler to him than our dad’s golf shirts were to us.
When there was no such thing as a PC, BASIC was without a doubt cool. But when a nine year old plays 3d games on an Xbox or Wii, there is absolutely nothing about low tech programming that appeals to him.
Consider it from his point of view: XBox games are cool. I can make my own games as cool as those (or at least in the same realm of coolness) by using Squesk or some other OOP game development tool. Why would I want to use those really picky languages to create flat blips of color that beep?
On the other hand, this 38 year old really likes your book idea ;)
M@
Comment on July 1, 2008 @ 11:56 am
M@ : On the other hand, the games I played on the SNES, even the 8-bit Nintendo, were way better than the things I was making, and yet programming text in BASIC still held its appeal for me.
I am directly challenging this idea that “programming needs 3D graphics and flashiness in order to be cool”. I don’t think it is as true as we think it is.
Comment on July 1, 2008 @ 12:06 pm
Aim high. Below pure drag-and-drop “programming,” but definitely at a very high abstraction level. If you want to get kids interested in programming, let them MAKE STUFF HAPPEN from the very start — and not just “hello world” stuff, but real game-like events. Give them a graphics toolkit to import, let them send critters scrambling around the screen, give them something extremely play-with-able that yields instant and fascinating results. Take Processing as an example: non-programmers are able to fiddle with Processing scripts and create seriously nifty stuff.
Then, if the kids start to say “well this is all great, but what if I want to do X?” Go down a level.
Comment on July 1, 2008 @ 12:21 pm
Interesting ideas. Personally I say we should teach the essential procedural languages like fortran and c, before we have students learn anything else. Just as you would want them to know Newton before they tackled Einstein, I think the fudamental principles of turing machines, algorithms, etc. need to be enforced along with a classic language like c. Then at that point they can learn some of the more recent approaches. Just a thought.
Comment on July 1, 2008 @ 12:25 pm
teach children how to make firefox extensions; then they will be useful minions, muwahaha.
seriously, though. i think that if you could get a group of widgets around, that they could use, it would be a lot of fun. learning the “framework” is very very important to programming. give them a framework, and let them use it! teach loops, conditionals, input/output, functions, classes. don’t bother teaching them System.Out.Println(). they’ll have do deal with that soon enough. ;)
Comment on July 1, 2008 @ 1:00 pm
I agree with Alan about the importance of making stuff happen as quickly as possible. Say what you will about Visual Basic (where I was introduced to programming), it allows a kid to make neat looking things very quickly. I wouldn’t touch VB these days, but when I was first starting out, it was just the thing to get me hooked.
Comment on July 1, 2008 @ 2:45 pm
Ah, I am teaching my 9 year old to program and just stumbled on your blog. Here are my thoughts/observations/etc
1. There is absolutely no way you can teach a 9-year old any kind of theoretical principles (as was suggested by Frank). The math is simply not there.
2. Drag and drop environments are bad for teaching, they make easy things easy, everything else impossible. They just distract from the programming concepts (I tried NXT-G for Mindstorms)
3. Special purpose languages like Logo might be useful, but kids do grow out of them. Not sure how fast that normally happens.
3. Fortran? Was that a joke?
4. C may be a difficult 1st language for a 9-year old. A lot of low level details. But there is one niche where I think C may be a reasonable choice: Mindstorm programming. 9 year olds LOVE Mindstorms.
5. Java. Oh, well, try to explain
“public static void main()”… And, I think, loops, variables, functions need to be studied before OOP, so I don’t think Java is a great choice either.
6. Python. I think python fits the task very well: it’s high level (not verbose), it scales into pretty much every niche, it’s x-platform..
7. Finally, I think that graphics should be studied as one of the first things. It’s very interesting for the kids and allows them to do something which they can show to friends.. Btw, I think plain tkinter is pretty good for teaching graphics: just hide creating of toplevel window and the canvas and you can draw any object and most importantly, it’s very easy to move them. So easy to create animations, etc.
8. I dont see much point in bothering with curses, etc.
Comment on July 1, 2008 @ 8:06 pm
I, too, learned programming in the 80’s on MSX BASIC. I think it’s the nearest thing to an ideal environment for teaching programming.
Basic has the advantage of being somewhat near to the machine model while retaining the ability to make interesting stuff.
My position on teaching programming is that the new programmer learns best when he does by hand what advanced compilers usually do automatically. Basic forces you to really plan out your program, since all variables are global and there’s no data abstraction, you have to implement the “magic” yourself instead of depending on the compiler to do it for you. While the graphics capabilities give you a nice reward to make it all worth it.
Last year I was training some C beginners and I created a simplistic graphics library to let them make games with. I copied the MSX basic design to the letter, including a hard limit of 30 sprite limit and only the basic 2D drawing primitives. I have a pet theory that minimalism drives the creative mind and I wanted to see the students think about designs and trade-offs and to find creative tricks to work around the limitations. Going too high level and making 3D graphics/animation easy would send the wrong message IMO.
Comment on July 1, 2008 @ 11:13 pm
I started working last fall as the technology director of a boys college preparatory school, by my background is commercial embedded software development. The school has had 5th and 6th grade computer classes for several years that taught Logo, and as I talked to the teachers, I learned that while the classes were very popular 8 years ago, now it seems like the boys are bored and difficult to motivate. They end up covering less material with less understanding than they did in the past.
So, we tried switching the 5th grade class to Scratch last Spring and the results were amazing. They were clearly excited about what they could create, and they not only quickly did the work assigned, but experimented and went far beyond the assignments.
Interestingly, before I started investigating alternatives, I was biased towards teaching a mainstream language like Python, but as I learned about Scratch, I thought it might be worth a try. Also, our teachers were at first averse to the seeming “toy” feel of Scratch, and what they perceived as limitations compared to Logo. However, they were very favorably impressed by the students reaction, so we are switching to Scratch for both 5th and 6th grade next year.
One thing to consider is that these computer classes are in the core curriculum, so every student has to take them. All of our students have to be pretty smart to even get into our school, but only a few of them seem to be interested in computer programming. For someone who is already motivated to learn programming, the low-level approach advocated by Al may serve them well.
This fall I will be teaching a Game Programming elective at the High School level using Game Maker, which is another drag-and-drop system. I will see how that goes and if I determine we have a group of students who would be interested, I will try another course later which is lower-level using PyGame or Pyglet.
Comment on July 2, 2008 @ 11:17 am
I learned to program before I was 8 mostly using basic on early microcomputers, and then I taught myself assembly language.
What I recall, was that the most important thing to me was to be able to make ‘real’ programs that were comparable with the commercial ones that were available. I didn’t want to be using some special ‘educational’ environment or language. At that time, real software was written in basic for these machines so there was no stigma associated with it.
What most closely parallels this today? I’d argue that it has to be PHP. Web applications are a huge class of what have to be considered to be ‘real’ applications today. PHP is remarkably basic-like, and you don’t have to do very much to get something that resembles what commercial sites do.
I am certainly not suggesting that PHP is a good language for teaching either the fundamentals of programming, or abstraction, or good style. Far from it - I think it’s terrible in all the same ways that basic was terrible.
It would however let kids get real things built relatively quickly, and it isn’t a toy.
Comment on July 2, 2008 @ 4:51 pm
What makes this question difficult is that what you are asking is partly marketing. “Okay, we want to sell them this idea, do we use the big box or the little box?” In the end, if you can sell it then it doesn’t really matter which way, people will pick what appeals to them.
What *seems* to sell very well is the idea that you can achieve much without doing much work. That is what the current ruby-rails movement is all about. Whether that’s true or not is secondary, the crucial thing is the sales pitch.
Comment on July 3, 2008 @ 2:00 am
Well, I believe that programming is definately appealing to a younger audience, for example I have been learning web design for 4 months though I have been busy so havnt really learned much.
I find myself often turning to 13 year olds to help me with my problems, they have been learning for years.
I have just turned 16
Comment on July 3, 2008 @ 8:34 am