Amy has been interested in creating her own video game for a while now, so I started looking for easy ways to get an eight-year-old started with programming. It quickly became clear that Scratch was the best choice, not only because of the environment itself but also because of the community that has built up around it, so I downloaded the Mac version and we started playing some of the demos. There’s one called Fruit RPG that seemed pretty close to the kind of game we wanted to create. You get up, walk around collecting fruit, then go into the “fruit place” where someone rewards you with a fruit platter – simple stuff, mostly there as an example of lists in Scratch. After Amy went to bed, I started digging in a bit so I could be several steps ahead of her and ready to answer questions when she asked instead of having to figure them out on the spot. My idea was to learn by adding a couple of new features – a poisonous mushroom that would kill you when you picked it up, and a dinosaur that would follow you around trying to steal your fruit (shades of Adventure there). I was able to implement both fairly quickly, but also discovered a couple of bugs.

  • The fruit were infinitely regenerating. Every time you went into a building and then came back out, all of the fruit were there even if you had already collected some.
  • If you walked to the spot on the screen where the fruit-place guy would be if you were in the store, the ending sequence would start even if you were outside.

I’m sure the people who wrote this little example didn’t care about the first, and probably the second either, since this was just an example of using lists anyway. Nonetheless, it seemed likely that I’d learn by fixing them. It turned out to be a bit more of an exercise than I’d thought, because the “scripts” to make things appear and disappear as you change location are intricately tied to the language’s message-passing paradigm. You leave your house by moving over an invisible door object, which as part of its operation broadcasts a message. The background object responds to this message by drawing the outdoor scenery, the fruit objects respond by making themselves visible, and so on.

This got me thinking about some aspects of the message-passing system. For example, does a “broadcast and wait” action mean that the message gets enqueued everywhere before it’s processed anywhere, or would various overlaps be possible? This was important because it would affect whether a second message sent from one of the response scripts was guaranteed to come after the original message, and the viability of some possible solutions hinged on the answer. I wondered how many young programmers had been frustrated by the weird semantics of the “forever when X” action (not “while X” but “if X” within an infinite loop), by having the wrong expectation of whether the “green flag” message is processed synchronously or asynchronously, by not realizing that multiple instances of the same script could run concurrently, and so on.

Needless to say, I fixed the bugs and added my features pretty easily. Along the way, I came up with a general set of “best practices” (essentially actor model) that avoid the pitfalls mentioned above. That’s all nice, but it’s not the real point here. The real point is that careful specification of a system’s behavior isn’t just something that you do for the sake of advanced programmers. Even a simple system like Scratch can involve significant complexity and ambiguity. Even the most inexperienced programmers trying to do the simplest things might get tripped up by details that you didn’t bother to explain. Scratch is a nice little system, but it might be nicer if it didn’t leave my daughter and other children like her trying to debug race conditions. Think about that next time you’re tempted to say that an implementation choice was obvious because users would be able to figure it out.

P.S. I wrote most of this a couple of days ago and wasn’t even sure I’d ever get around to posting it (I have dozens of drafts like that), but it seems particularly timely in light of this book review that was posted today so I might as well let it fly.