Rust is not fast

There are plenty of safe high-level languages in the world; JavaScript, for example. Rust is different: it's supposed to be safe and fast.

But Rust is slow. (And its type system hates you.)

Rust is slow because there is lots of hidden indirection ("smart dereferencing") and other hidden costs (ref counting, etc). In low-level C code I can look at a line of code and know roughly how many (slow) memory accesses are present. Not so in Rust.

Further, Rust's type system leads to extra unnecessary copying, just to get your code to compile without massive refactoring of the standard library. When writing rusty-turtle I found myself having to add ~ or @ pointers to my types (forcing extra layers of dereferencing) just to work around the type system. Further, the APIs have a genericity problem: there are lots of duplicate methods, since &-pointers aren't truely generic/orthogonal. (And you will find yourself duplicating methods in your own APIs as well, in order to be able to pass in parameters with different reference types -- or else just throw up your hands and wrap an extra @ layer around everything.)

The ownership type system also fights against typical APIs like find_and_insert for maps, since you don't know (before you do the find) whether or not you will be giving up ownership of the parameter (in order to do an insert). So you just copy the inserted value, always! Cycles are cheap, right?

Rust is also slow because it is not built to be parallel. The language is concurrent, but this is a word game: in the past few years the terms have been redefined such that "concurrent" is (roughly) non-blocking cooperative multitasking (such is implemented by node.js and GNU Pth), and "parallel" is reserved for actually doing more than one thing simultaneously (whether on separate CPUs or separate cores of a single CPU). Rust's memory model doesn't help: there is no shared memory, and ownership types make fork/join parallelism difficult. All inter-task communication is explicit message passing, with the races that entails. (Perhaps I'm spoiled: the Cilk work-stealing nano/microscheduler is my benchmark for speed.)

Some possible improvements:

  • Get rid of smart dereferencing; make it clear when performance is impacted by memory references.
  • Fix bugs with small objects/ABI limitations to avoid unnecessary parameter wrapping.
  • Make & pointers truely generic (or invent a new pointer which is) and do template expansion/method splitting to generate the proper specialized version of the method automatically (although this will exacerbate existing problems with code caching).
  • Better support fast refcounting/fast gc (update coalescing, generations).
  • Support fork/join parallelism and work-stealing.

This post is written from my experience with Rust in May 2013. Some of these problems are known, and some may eventually be fixed. But it makes me wonder what the language is really supposed to be good at. There are already plenty of slow safe languages.

JavaScript in asm.js (and a little rust)

Over on twitter, Tim Caswell mentioned, "I think high-level scripting language on top of something like would make for an amazing OS." and that set me off a bit. Twitter isn't a great place to write a reasoned discussion of programming languages or implementation strategies, so let's take a shot at it here.

As I've written about on this blog, I've been tinkering for years with TurtleScript, a small learnable JavaScript subset in the spirit of Alan Kay. Over in that twitter conversation David Herman mentioned rusty-turtle, my TurtleScript bytecode interpreter written in Rust. The rusty-turtle codebase includes a REPL which runs TurtleScript's tokenizer, parser, bytecode compiler, and standard library (all written in TurtleScript) through the Rust interpreter. It's quite cute, and I implemented much more of the JavaScript semantics than I strictly needed to (with the side-effect that the behaviors in the JavaScript wat talk now appear quite sane and sensible to me).

I wrote rusty-turtle as a personal warm-up: I was considering taking a job with the fine folks at Mozilla (OLPC having run out of money again) and wanted to understand the technology better. I described a number of further research projects I thought would be interesting to pursue in the rusty-turtle README, including cilk-style fork/join parallelism or transactional memory support (the latter being the subject of my thesis), and a JIT backend using rust's llvm library bindings.

But the true turtles-all-the-way-down approach would be to rewrite the backend using asm.js, which can be trivially JIT'ed (using llvm bindings). Then you've have an entire system from (pseudo-)assembly code up, all written in a consistent manner in JavaScript. To that end, I wrote single-pass type-checker/verifier for asm.js in TurtleScript, discovering lots of issues with the spec in the process (sigh). (I justified this as more "Mozilla interview preparation"! Besides, it was fun.)

Tim Caswell, to finally answer your question: I think that this "JavaScript all the way" system would make an amazing OS. The Rust stuff is just a distraction (except as needed to bootstrap).

In the next post I'll rant a bit more about Rust.

ps. In the end I over-prepared (!): Mozilla's feedback was that I seemed to "know too much about Rust to work on Servo" (Mozilla's experimental web layout engine, written in Rust). Mozilla seems to have reached that awkward size where it can not longer hire smart people and find places for them to contribute; new hires need to fit into precise job descriptions a priori. That sort of place is not for me.

SDR 0.7

Happy Thanksgiving! Here's SDR 0.7 to celebrate the holiday. Version 0.7 incorporates a number of dance engine refactorings completed shortly after the previous release promised them, as well as (more recently) a number of new call and concept definitions (and test cases) inspired by the C4 calls I am currently studying. I also updated Google App Engine and Google Web Toolkit to the latest versions for the web app, although jMonkeyEngine is still stuck at 2.0 — we might get an Android version of SDR if I manage to rebase to jMonkeyEngine 3.0 for the next release.

Breathing the square properly is still a challenge. Other square dance programs only treat starting and ending formations, but SDR has to consider all of the intermediate positions along the dancers' paths. This leads to some very unusual formations being breathed. As mentioned in the notes for the last release, SDR formulates breathing as a solution to a mixed integer linear programming problem—but there are still a few bugs lurking which cause the constraint solver to blow up from time to time (especially from columns, for some reason). Hopefully I'll be able to dig into this for the next release.

Reading Project Talk (and slides)

An unruly tag team of OLPC folks gave a long talk on the Literacy Project today for attendees at this year's OLPC-SF Community Summit. It was streamed live on Ustream: Part 1 (Matt Keller, Richard Smith), Part 2 (Richard Smith, Ed McNierney, C. Scott Ananian, Chris Ball, questions from the audience). We've posted the slides: Matt Keller, Richard Smith, C. Scott Ananian.

You can try out some of the apps mentioned in the talk. Nell's Balloons and Nell's Colors will run in any reasonably-recent Google Chrome or Mozilla Firefox browser. They will also run as a Firefox webapp on Android devices, using the latest Firefox nightly for Android. For deployment we use a slightly-tweaked build of Firefox (adding expanded webapp storage quotas and the ability to use plugins from inside webapps), and a custom plugin to hook up the Funf logging framework. Source code is available on github: nell-balloons; nell-colors. In addition, Chris Ball's "Matching" app for Android is available: apk; source.

The Importance of Sensing Distance

At IDC 2012 in June, Arnan Sipitakiat and Nusarin Nusen discussed how they are using Robo-Blocks—a turtle robot and “tangible Turtle Blocks”—to teach problem solving and debugging skills to 5- through 12-year-olds.

One of the things I learned from their presentation was that children had difficulty reasoning about relative angles. The Robo-Blocks robot does not have any distance feedback on its motors, so “the result of a program will change depending on the roughness of the surface and the battery level of the robot.” They worked around this issue by developing a protractor tool to guide the children's reasoning about the relationship between the (arbitrary) numbers entered and the amount the robot turned, but some kids still had difficulty. The researchers “often had to insist on trying the protractor” and “some children preferred to keep increasing the turn amount even if a small decrease would have fixed the problem” resulting in programs that had the robot making multiple complete rotations before setting off in the correct direction. The kids were also dissatisfied with polygon-drawing tasks (“turtle geometry”) because the inaccuracies of open-loop control of the robot means that the polygons often didn't close completely, and “[t]his small error turned out to be unacceptable to children.”

So I designed the XOrduino turtle robot from the start to have distance sensors so that it can do accurate turns with closed-loop control. Here's a little video showing how they work in the current (A1.5 / B1) revision of the board:

Some bonus pictures of the speed sensor on the workbench:

  • The robot on the workbench with probes.
    Speed sensor test setup
  • Signal from the motor speed sensor. 5ms/div .5v/div. Motor is running at full speed, unloaded. Two dips are seen: the larger is from a piece of white paper glued to the rim of the gear; the smaller is from a spot made with a white paint marker (the paint didn't stick very well). White-out worked much better (as shown in the video above).
    Oscilloscope trace
  • Oscilloscope settings
    Oscilloscope settings

XO Turtle Bot drives around

Here's a first look at an XOrduino Turtle bot driving around:

I've checked out all of the functionality on the A1.5 board except the step-up voltage regulator now. I'm optimistic the B1 boards (being made now in Taipei) will be clean.

It will be great when we've got lesson plans written up so kids can learn how to control the bot with Turtle Blocks, and play with the different possible behaviors. Instead of just bumping around ("like a Roomba, except it doesn't vaccuum" a friendly 6-year-old beta-tester told me), you can trace patterns you design, or use the Scratch Sensor Board sensors to make the robot "afraid of sound", "attracted to light", or add your own sensors and behaviors.

Tags: ,

"Hello, World" from XOrduino/XO Stick

Here's a quick look at the next versions of the XOrduino and XO Stick boards. These were assembled from a small quantity of "pre-B1" boards I had made at BatchPCB.

I've uploaded some more pictures to the XOrduino album as well.

Here's a little table relating the board versions pictured with those I've previously discussed.

BuildXOrduinoXO Stick
This videov6v7

B1 is "the next run" of boards, already released to the fab house but not yet in hand.

The big feature added to XOrduino after A1 was a motor driver, to allow using the XOrduino as a Turtle robot. The big feature added to XO Stick after A1 was the shield form factor, allowing it to ride piggy back on the XOrduino. This makes it easier to share a single turtle robot with a classroom: there may be only one XOrduino robot base, but each student can have their own low-cost XO Stick "brains". They can take turns snapping their brains on top of the base to drive it.

I haven't finished testing all the functionality of these new boards yet, but it looks like I haven't made any major mistakes! Help still wanted with software, documentation, etc; send email to if you're interested.

XO Bot joins the XOrduino and XO Stick

Free things first: I've got parts for 20 copies of the "Mk I" XOrduino and XO Stick. I'm mailing them out for free (!) in exchange for your development help. Send me an email at describing what you'd like to do with the XOrduino/XO Stick, and your full mailing address. Best 20 or so get kits.

XOrduino A1

Here are some of the projects which you might be able to help with:

  • Assemble an XOrduino / XO stick with an 8-12 year old and document the process. What parts were tricky to solder? Where did polarity matter? How much of the function of the different devices did you find worth explaining? Photos or video of children assembling the device would be great for future publicity, with their permission. (We're not crazy: kids can repair XOs and solder.)
  • Test different configurations of the boards. What are the fewest components necessary for a functional XO Stick? What capacitors are really needed? What's the smallest number of components needed to get the arduino IDE to talk to the XOrduino? Then add the components for the Scratch Sensor Board functionality, and test that with this Arduino sketch (some minor porting required). Try out whatever Arduino shields/old Arduino code you have lying around, and see if there are any gotchas there. Document it all, take photos and video, let me know about bugs and pitfalls.
  • Write some killer education apps! These boards are meant specifically for teaching kids—take the Turtle Art with Sensors ideas as examples, and write up some lessons to teach science. Or take inspiration from the old school "fun with electronics" kits from Radio Shack and recreate some of the popular standbys: a burglar alarm for kids' tree fort, a light-sensitive alarm they can hide in their sibling's drawer, etc. Or a document how to program a robot (more on the robot below) with simple emergent behaviors—avoiding walls, turning toward light, fleeing loud sounds, etc. The Cubelets examples may give you ideas. Take photos and video.
  • Arduino support for the XO Stick. There are a number of projects which add support for the ATtiny85 and friends to the Arduino IDE (for example, this one). Ideally we'd like to make the XO Stick as Arduino-compatible as possible, so we can reuse the excellent Arduino IDE, etc. This involves (a) porting an arduino-compatible bootloader (like usbAspLoader-tiny), as well as (b) porting the Arduino libraries to match the pinout/peripherals of the ATtiny85 and ATtiny861 (this page is a good start).
  • Program an XO Stick from an XOrduino and vice versa. Ideally we'd like to bootstrap the initial chip programming, so that one programmed XOrduino (or XO Stick) can be used to put the initial bootloaders on the others. For technical reasons the XO Stick is probably best as a "clone tool": without interacting with the USB bus it would just copy its internal memory to another XO Stick. The XOrduino is a little easier, just a matter of adapting the existing Arduino sketches and documentation.
  • Debrick an XO from the XO Stick. The XO Stick can talk to the EC programming bus to recover a bricked XO; it can probably also reprogram OpenFirmware. We need to write a bit of code to make it pain-free and document the process. This would make the XO Stick a useful repair accessory for XO deployments.
  • Scratch/Turtle Blocks support for the XOrduino and/or XO turtle bot (see below).

Here's the exciting part two: I'm already working on the XOrduino and XO Stick "Mk II". The latest schematics/boards are in github (xostick, xorduino). The kits I'll be sending out this week correspond to the "A1" tag in those repositories; the "Mk II" revision is on the master branch.

The XO Stick gets a minor change with big implications: instead of using a 20-pin header matching the ATtiny861 pinout, I've widened the board to give the XO Stick a standard Arduino shield connector (and some prototyping area). This opens the way for a port of the Arduino IDE (mentioned above), but it also means that the XO Stick can be mounted on top of an XOrduino. In a cost-conscious classroom environment, this allows a teacher to buy/make one copy of the XOrduino with all of its fancy peripherals (scratch sensors, robot support) and then give each student a copy of the cheaper XO Stick. The students share the XOrduino and swap out their XO Stick "brains" on top to control it or use its peripherals. Mating the two boards also makes it straightforward to program an XO Stick from an XOrduino, or to use the XO Stick's prototyping area to hack together a shield for the XOrduino.

The XOrduino gets a more exciting feature (hinted at above) -- enough peripherals to become the XO Turtle Bot! This is a very low-cost turtle robot based on a Tamiya motor assembly. All of the extra robot components are optional—you can populate just the parts you want—but a classroom can now make their XOrduinos (or XO Stick + XOrduino base) into standalone turtle robots, controlled by Scratch, Turtle Art, or Arduino code. The XO Turtle Bot revision adds a motor driver, two bump switches, a simple 3-cell power supply, and rotation sensors for the motors to the XOrduino. (Arnan Sipitakiat and Nussarin Nusen in their Robo-Blocks presentation for IDC 2012 explained that children find "turn for two seconds" hard to understand; we include motor sensors so that we can "turn 90 degrees" instead.) And of course because the robot is based on XOrduino, you can add whatever other sensors you like and write arduino/Scratch/Turtle Blocks code for it.

XOrduino A1 board on top of Tamiya Twin Motor Gearbox.   XOrduino A1 plugged into USB port; prototype XO Turtle Bot in the background.

I'm excited about the potential of low-cost robotics and the Arduino platform for education. If you are, too, let me send you a kit so you can help out!

Nell's Tinkrbook in Omo

This week I will be at the 2012 Interaction Design and Children conference in Bremen, Germany. I will be presenting the Growing Up With Nell paper as well as discussing the OLPC Foundation's literacy pilots in Ethiopia.

The Literacy Project is a collaboration between four different groups (as alluded to by the title of this post): the One Laptop per Child Foundation (“Nell”), the MIT Media Lab (“Tinkrbook”), the School of Education, Communication and Language Sciences at Newcastle University, and the Center for Reading and Language Research at Tufts University (“Omo”). The goal is to reach children even further from educational infrastructure than OLPC has ventured to date. In particular, the Ethiopia pilots are complete child-led bootstraps, attempting to teach kids to read English (an official language of Ethiopia) who neither speak English nor read in any language yet. There are no teachers in the village, and no literate adults either.

Adapting Nell to this environment has some challenges: how do we guide students through pedagogic material with stories if they don't yet understand the language of the stories we want to tell? But the essential challenge is the same: we have hundreds of apps and videos on the tablets and need to provide scaffolding and guidance to the bits most appropriate for each child at any given time, just as Nell seeks to guide children through the many activities included in Sugar. In the literacy project there is also a need for automated assessment tools: how can we tell that the project is working? How can we determine what parts of our content are effective in their role?

I'll write more about the Literacy Project in the coming weeks. As we've started to get data back, some of the lessons learned are familiar: kids do the strangest things! They learn how to do things we never knew they could do (or meant for them to) and often are motivated by pleasures which surprise us. For example, one app we deployed had a sphere which deflated with a sort of farting noise when the child picked the wrong answer. It turns out that the kids liked making the farting noise much more than they liked the response to the correct answer! Obvious in retrospect, but the lesson reminds us why we are pursuing an incremental development and data collection approach. Happily, the hardware itself has been a success: low hardware failure rates, solar powered charging is successful (although they prefer to charge the devices during the middle of the day; we'd expected them to do so overnight from storage batteries charged during the day), and they've mastered the touch interface very quickly on their own. The pilots have been running since February, and the kids are still very engaged with the content. So far, so good!

Smiling boy in Ethiopia Literacy Pilot Two girls in Ethiopia Literacy Pilot

Tags: , ,

Introducting the XOrduino! (and XO Stick)

I banged out two open hardware designs this week, designed for use with the OLPC XO laptops.

The first is the XOrduino, a stripped down low-cost Arduino-compatible board that plugs right into the XO's USB ports. But wait, there's more: it's also compatible with the Scratch Sensor Board, so you can use this device to control Scratch (and Turtle Art, once Firmata is ported). It should be compatible with the Arduino IDE and all Arduino Leonardo-compatible shields.

The board uses mostly through-hole parts, with one exception, and there are only 20 required components for the basic Arduino functionality, costing about $5 (from digikey, quantity 100). It is reasonable for local labor or even older kids to assemble by hand.

It's open hardware: Eagle design files are on github (schematic PDF, pcb PDF). I expect to have a small number of boards in a few weeks; let me know if you'd like one in exchange for help with hardware and software bring-up. Schematic and layout review also appreciated (I did the PCB routing late at night under time pressure leaning heavily on autoroute, it's certainly not the prettiest). And feedback from Arduino and Arduino shield hackers would also be welcome.

If $5 per student is too much money, there's also the XO Stick, my second board. It's based on the AVR Stick using the ATtiny85 processor and costs only $1/student. It's not quite as user-friendly as the Arduino-compatible board, but it can also be used to teach simple lessons in embedded electronics. For $0.12 more you can populate an ATtiny261A (though a '461 or '861 would be better) and get 13 I/O ports; this variant should be powerful enough to program other XO Sticks and perform XO maintenance tasks (accessing the serial console, debricking a laptop via SPI flash). The XO Stick is even easier for a kid to assemble themself: only 8 required components, all through-hole. (Sadly, my desire to shave every penny off the cost of this design meant that I couldn't use some of the symmetry tricks I invented for a 2012 Mystery Hunt puzzle to make the circuit impossible to assemble incorrectly.)

Same deal as the XOrduino: design files on github (schematic PDF, pcb PDF); I expect to have a few boards available to people who want to help make some software for them. Schematic and layout review is also appreciated!

Growing Up With Nell

Chris, Michael, and I just submitted a short paper describing our work on the XO-3 Nell project to this year's Interaction Design and Children conference. Give the preprint a read: Growing Up With Nell: A Narrative Interface for Literacy [pdf].

We're hard at work implementing Nell. We could use help in a number of areas: art, animation, story, user interface, javascript hacking, and probably others. For example, at the moment Chris and I are: drawing the characters, drawing user interface concepts, writing silly alphabet stories, animating the silly alphabet stories, doing the CSS/HTML layout to mock up designs, making some of the mock ups into functional demos, implementing HMM-based handwriting recognition in JavaScript, porting pyaiml to JavaScript, implementing an Apple Guide-style contextual help system on top of HTML widgets, and writing a integrated story editor (and stories about the story editor). I'd welcome volunteers for any of these tasks!

Tags: , ,

A collection of Nell demos

Here are some banged-together demos of various pieces of One Laptop per Child's Project Nell. The ultimate goal is a Nell demo for CES in January 2012, but these bits should be considered as tech demos, benchmarks, and proofs of concept, not actual pieces of that demo (yet).

Most of these demos require WebGL support. Visit for information about enabling WebGL in your browser; there is WebGL support in Chrome, Firefox, Safari, and Opera—although it often requires enabling experimental features in the browser preferences.

  • Tiles. Performance benchmark for a tile-based home screen. "Apps" are "locations" on your world map, which you can customize as you like. (Here's an interesting blog entry discussing world-creation for kids.) Day/night would ultimately reflect current time, although they've been greatly sped up in this demo. Lots of rough edges and missing UI, but all the textured triangles are present, so it should be an accurate benchmark.
    (Drag with left mouse button to rotate, middle mouse button to zoom, right mouse button to pan.)
  • Nell at home. Basic idea (including transition) for activities which include dialog with Nell or story-telling.
    Standalone model viewers: Castle (from blendswap), "Nell" (Sintel, from blendswap), Alternate (lightweight) Nell model, Alternate (heavyweight) house model (from blendswap).
    In model viewers: drag with left mouse button to rotate, middle mouse button to zoom, right mouse button to pan.
  • Music maker. Uses WebGL and the Web Audio APIs to let you draw and perform music.
    Inspired by André Michelle's ToneMatrix and Karplus-Strong Guitar (see also wiki and this 2008 Linux Audio Conference paper), as well as DinahMoe's ToneCraft and the Tenori-on.
  • Quake on XO-1.75 (video). Of course we need to actually run WebGL with good performance on XO hardware. Jon Nettleton has been working hard on our GL drivers, enabling the GPU on the XO-1.75 hardware for the first time. This Quake demo shows his progress—don't worry, Quake is not actually part of the Nell demo! (We have a GPU in the XO-1.5 as well, which hasn't yet been utilized.)
  • Codify—not one of our demos (it's a commercial iPad app) but it demonstrates the direction we'd like to push Pippy.

Coming soon: TurtleArt and Implode for the web. We've started converting them to GTK3 in preparation for hoisting them bodily onto the interwebs. Here's the source code repository for the TurtleArt port if you'd like to watch or participate in this hackage. (See for one of the more unusual ways to get Python running in the web context.) The rest of the demo source code is on github (or just "View Source" in your browser).

Tags: ,

Introducing Nell

Between now and January CES, Chris Ball and I will be building Nell for the OLPC XO-3 tablet. Nell is a name, not an acronym, but if you want to pronounce it as "Narrative Environment for Learning Learning," I won't stop you.

Nell's development will be demo-oriented—we're going to try to write the most interesting bits first and learn as we go—so don't be upset if you don't see support right away for legacy Sugar activities ("Sweet Nell"), robust sharing support, mesh networking, or whatever your favorite existing feature is. They'll come, but the new crazy stuff is what we need to evaluate first.

Here are four of the big ideas behind Nell, along with pointers to some of our sources of inspiration.

Narrative. I probably don't need to restate that Neil Stephenson's "The Diamond Age" has been hugely influential, and we also owe a large debt to interactive fiction and the Boston IF group in particular. (Check out the talks from our "Narrative Interfaces day" at OLPC.) Wide Ruled (conference paper) and Mark Riedl at Georgia Tech have demonstrated interesting approaches to story representation. I'm also looking forward to the results of the Experimental Game Play group's September Story Game competition.

Emotion. The Radiolab podcast "Talking To Machines" crystallized my thinking about emotionally-attractive environments. The discussion with Caleb Chung, the creator of Furby, is particularly apropos. Caleb's goal is to make things which kids want to "play with for a long time," and he contributes his three rules for creating things which "feel alive": it must (1) feel and show emotions, (2) be aware of itself and its environment, and (3) have behaviors which change over time. Furby's pursuit of these goals include expressive eyes and ears, crying when held upside down, reacting to loud noises, and gradually switching from Furbish to English for its utterances. A living thing emits a constant stream of little surprises. Expect to see Nell put the XO-3's microphone and accelerometer to good use.

Talking and Listening. The "Talking To Machines" podcast also discusses ELIZA and Cleverbot, which dovetails with my interest in the popular Speak activity for Sugar and related toys like Talking Tomcat for mobile phones. The key insight here is that a little bit of "cheap trick" AI can go a long way toward making a personable and engaging system. We want Nell to feel like a friend. Recent work by the Common Sense Computing Initiative at MIT's Media Lab shows how we can reset this on a sounder basis and use mostly-unstructured input to allow the system to grow and learn (creating "behaviors changing over time"). In particular, I'll cite ConceptNet for its database and practical NLP tools, and inspiration from "Empathy Buddy," "StoryFighter," and the other projects described in their Beating Common Sense paper. It's also worth noting that open source speech tools are good and getting better (the VoxForge site points to most of them); also interesting is this technique for matching a synthesized voice to that of the user.

Collecting, nurturing, and rewarding. Collector games such as Pocket Frogs and Flower Garden are sticky activities which encourage kids to come back to the device and continue working toward a goal over a long period of time. Memrise is educational software illustrating this technique: its users tend a garden of flowers by mastering a set of flash cards. Nell will incorporate the sticky aspects of such games, possibly also integrating the Mozilla Open Badges infrastructure into an achievement/reward system.

I hope this has given you a general sense of the direction of our Nell project. In future blog posts I'll drill down into implementation details, demonstration storyboards, and other more concrete facets of Nell.

Tags: , , ,

Narrative Interfaces

One Laptop per Child creates student-centric learning experiences. Our current software stack, however, is somewhat "shallow". When you turn on the XO, all the content is immediately available but there is no path or guidance provided. Nothing suggests what you should try first, or indicates an order to progress through the activities provided. Everything is available, but there's no built-in journey. No plot. How can we improve this?

This Friday (June 17) at 2pm Eastern we're inviting some folks over to OLPC's new offices at the American Twine building to discuss Narrative Interfaces, as part of the proposed XO-3 software stack. Nick Montfort will give a short talk on Curveship, his model-based interactive fiction system, and Chris Ball will present some related recent hacking. Angela Chang will present her Tinkerbooks early-literacy platform, which allows kids to interactively change the written story on the page. And I'll discuss Neal Stephenson's novel The Diamond Age (a recap of a short talk I gave at EduJAM in Uruguay), and give concrete suggestions for how Diamond Age's Primer might influence the software architecture for the XO-3. (I might even reveal how to make software testing semantically indistinguishable from writing a game!) Chris Ball and I have also been collecting best-of-breed "comic books that teach you something" as examples of educational narrative; we'll pass those around and post a reading list after the event.

The real point of this meeting isn't the talks, per se, but the discussions to follow. We're trying to gather folks who know a lot more about this stuff than we do, in order to learn from them and be inspired. We don't have a lot of space, unfortunately, so I'm going to have to ask for RSVPs from those who wish to attend. If you're in the Boston area and feel like you have something to contribute (and especially if you have created/could create Creative Commons-licensed content for education), drop me a line at cscott at laptop dot org. Describing what you can contribute to the discussion will help break ties if space is inadequate.

We will also live-stream the meeting at Afterwards we'll post higher-quality video and a list of cited works. Thanks in advance to everyone who will participate, online and off!

UPDATE: video now up; see this writeup on Chris Ball's blog.

Small systems... and distributed ones

Today I stumbled across some very interesting projects by Nickolay Platonov which I'd like to discuss in an OLPC context.

I've been hacking away at TurtleScript fueled partly by a drive for minimalism: a small system is a learnable system. To that end, the language is based on Douglas Crockford's "Simplified JavaScript" (as recognized by this top-down operator precedence parser) which tries hard to include only JavaScript's "Good Parts". For example, the initial code for the TurtleScript system uses prototype inheritance (via Object.create) rather than classical class-style inheritance. In fact, the new operator isn't even included in the Simplified JavaScript/TurtleScript language.

In a discussion of TurtleScript Alan Kay mentioned, "It is very tricky to retain/maintain readability (so the first Smalltalk was also an extensible language not just semantically but syntactically)." And today I stumbled across the Joose library, which gives a very readable syntax for traditional class-based inheritance. It backs this up with a robust meta-object protocol, introspection, and lots of nice features borrowed from Perl 6, CLOS, and Smalltalk. The syntax ought to work fine with the limited tile set of TurtleScript, although I might have to add a tile for the new operator.

However, adding Joose raises some questions. Is the increase in readability worth the addition of such a large library to the system? What impact will this have on understanding problems and debugging? Is a return to class-based inheritance a positive change? (There have been arguments that the make-a-clone-and-change-it practice of prototype inheritance is easier to understand for new learners.) Can a larger overall system actually be easier to understand?

And once we're looking at libraries... Nickolay Platonov is now working on Syncler, based on the Bayou system. Unobstructive replication mechanisms would certainly make it easier to construct the sorts of collaborative applications we've wanted for Sugar. I have two concerns with Syncler's current state. First, the use of explicit continuation-passing style greatly impairs readability. The JavaScript yield keyword helps a lot when writing asynchronous code. (It's not supported by all JavaScript engines, but yield wouldn't be hard to add to TurtleScript.) Second, Syncler's event model uses explicit callbacks. I've been greatly impressed with the Flapjax event model (and its strongly-typed functional cousin). Both of these changes ought to make asynchronous code much more readable—and isn't that an important part of grokking a system?

Turtles All The Way Down

Inspired by Bert Freudenberg, Ian Piumarta, and Walter Bender, I started hacking on "Turtles All The Way Down" (aka TurtleScript) on the plane back from Uruguay. Now there's a nice rendering demo to show what a tile-based editor for JavaScript might look like, as well as a bytecode compiler and interpreter for the language. The bytecode instruction set is still too large; encouraged by Craig Chambers' work on SELF I think I ought to be able to replace all the unary and binary operators, conditional jumps, and slot selectors by a single mapof operator. I can put a better object model on the interpreter, too; I've written some notes on the matter.

The question is: does this really have educational value? "Turtles all the way down" is a great slogan, and a fine way to teach a graduate-level class on compiler technology, but I feel that the higher-level UI for tile-based program editing is the really useful thing for tablet computing. I'm a compiler geek and love the grungy underbelly of this stuff, but I keep reminding myself I should really be spending more time building a beautiful fluffy surface.

EduJam talks

Chris Ball has done an excellent job posting video from all the talks at EduJam in Montevideo. I gave talks on Sugar, Education, and Tablets, The Diamond Age, Internationalization Everywhere, and Sugar on Android and Native Client.

Next Steps for New Technologies

I've reached the end of the month. I've accomplished my Android and NativeClient-related goals, but didn't get the time to do as much mesh and python investigation as I'd wanted. Here are some ideas for next month's work. (Next week I'll be in Uruguay for EduJAM.)

GObject Introspection (Android or NaCl)

  1. Start by porting libffi. An android port would be straightforward, but since libffi involves code generation (ARM, x86), this is going to require a bit of assembly magic and the new "JIT"/"shared library" support in the NaCl plugin.
  2. Then port gobject-introspection. GObject-Introspection relies on libffi for its guts, but the hard part of this port will be refactoring g-i's build process, which is not cross-compilation friendly. Might need to rewrite some tools. If targeting NaCl, you might consider finishing the code allowing execution of unsandboxed NaCl binaries.
  3. Turn gobject-introspection on its head: generate GIR and a C binding for the platform "native" interface. For NaCl, this would be a GObject-using C-level binding of the browser-native DOM; for Android, this would be a GIR binding of the native Android APIs. These bindings should be mostly automatically generated, since they will need to continue tracking successive native platform releases/HTML5 features.
  4. Demos! Change browser DOM from Python, write native Android apps in Python. Add a gobject-introspection binding to cforth, then do the same from forth. (Forth might be a simpler place to start than Python. Or not.)

GTK (Android or NaCl)

  1. Build on the cairo/pango port to proceed to a full GTK backend for Android/NaCl. These backends ought to be upstreamable. The NaCl port should be based on the broadway work: the cairo canvas would be drawn to more directly, but a lot of the mechanism which captures JavaScript events and translates them into the GTK event loop could probably be reused.
  2. Demo: "Hello GTK world" in Android/NaCl.

Sugar partitioning.

Bring Sugar closer to being a true multi-language multi-library platform.

  1. Refactor sugar modules (for example, sugar toolbar widget) as standalone C libraries. Basic idea is to embed Python and export a C API, while preserving as much of the code as possible. Python libraries now invoke this library via g-i-r instead of directly. The python embedding tool is probably a useful standalone product.
  2. Rewrite "Hello, Sugar" activity in C (or vala), using #include for import and GObject inheritance instead of python inheritance. Use this as a guide to pull apart sugar into modules (as above) to make this code actually work as written.

Miscellanous topics

  1. ChromeOS w/ touch support.

    Find an appropriate machine, do an installation, what are the roadblocks/rough spots? Can we install on XO-1.75 as a testbed?

  2. TurtleArt as JavaScript viewer/editor.

    Revisit TurtleScript work, but skip over the time-consuming "construct an editor" step by reusing the (excellent) TurtleArt code.

  3. Mesh: android olsrd frontend, build testbed, research 802.11 DCF issues.


There are four rough topics here; I might try to continue the breadth-first search by spending a week on each. It might be more satisfying to downselect two of these issues and spend two weeks on each.

Pango/Android -vs- Pango/NaCl

At the end of my Sugar/Android week, I had a simple Pango-on-Cairo demo running. This was built on a stack of ported libraries, including gettext, pixman, freetype, libxml2, fontconfig, and glib, as well as cairo and pango. You can run the demo yourself by sideloading pango-demo.apk onto your Android device (tested on a Motorola Xoom), and you can browse the source code to see what it entailed (here's the scariest part). (I was inspired by Akita Noek's android-cairo project, but I ended up reworking the build scheme and redoing most of the ports.)

Screenshot of Pango demo on Android

It made sense to start my Sugar/NaCl investigation by porting the same demo application to Native Client. The same stack of ported libraries was involved, although it was easy to include more functionality in the Native Client ports, including threading and PNG/PS/PDF support in cairo. The source code is a fork from the upstream naclports project, and the process was generally much cleaner. (But see my previous post for some caveats regarding naclports.) If you're using Chrome 10 or 11, you can run the demo in your browser (follow the instructions on that page). The Wesnoth team has a parallel project which ported some of these libraries as well, but not in an upstreamable manner.

Screenshot of Pango demo on Native Client

The demo app uses cairo to draw the background, an animated X, and some basic text in the center; it uses Pango's advanced international text support to draw properly-shaped Persian text in a circle around it. The center text is the "proper" bilingual Greek/Japanese written form of "pango"; the text around the edges is the Persian name of the internationalization library, "harfbuzz". Note that the Persian text is written right-to-left—and that I didn't put a full CJK font in the NaCl app, so the Japanese "go" character is missing. The Android port rebuilds the font cache at each startup, so it loads rather slowly; the NaCl port contains a prebuilt font cache so it starts more quickly.

Both ports took about two weeks. I blew my original schedule, partly due to the Patriot's day holiday, and partly because I'd given Android about a week's head start by tinkering on it before my original schedule post. The framerate of the demo is much better on NaCl (so fast that the edges of the animated X look choppy in the screenshot), but the hardware isn't easily comparable, so the comparison doesn't really tell us much. The porting effort was certainly more pleasant on NaCl, since newlib is a much more complete libc than Android's "Bionic"—but having gdb available made debugging on Android easier. (There is an unintegrated NaCl branch that integrates NaCl gdb in the browser, though!)

Much of the GNOME/POSIX library stack assumes access to a filesystem tree and does file-based configuration. In our demo application, fontconfig was the most culpable party: it wanted to load a configuration file describing font locations and naming, then to load the fonts themselves from the file system, and finally to write a cache file describing what it found back to the file system. Most ported software is going to want similar access—even if you store the user's own documents in a Journal, software still expects to find configuration, caches, and other data in a filesystem.

Android provides the POSIX filesystem APIs, but the filesystem an app can touch is segmented and sandboxed. As discussed previously, Android's Opaque Binary Blob feature may allow you to create a app-specific filesystem, but this doesn't let you share (for example) fonts and font configuration between activities. NaCl might eventually provide a similar unshared mechanism based on the HTML5 AppCache.

The preferred solution is more limited, but more flexible: no built-in filesystem APIs are used (or in NaCl's case, provided!) at all. Instead, you provide your own implementation of the POSIX file APIs (either via the --wrap linker indirection or through an appropriate backend to newlib/glibc/glib). For the NaCl demo app, I wrote a rather-elaborate in-memory filesystem --- only to find that an even-more-elaborate one already existed in naclports. But the longer-term solution uses message-passing (SRPC in NaCl, intents in Android) to implement these POSIX APIs. In Native Client, the implementation would be in browser-side JavaScript, which would then allow you to share parts of the filesystem tree between activities and/or map it into (cached) web-addressed resources. In either case, your application still sees the bog-standard POSIX API it expects.

More problematic are the networking APIs. Here Android provides a pretty standard socket library, while Native Client provides nothing at all. Using a browser-based implementation, as for the file APIs, will work fine for HTTP, WebSockets and even P2P via the HTML5 P2P APIs. But it's not clear that (for example) glib's elaborate asynchronous DNS name resolver implementation can (or should!) be implemented in a NaCl port.

In the end, the porting effort and abstraction shifts needed for Native Client and Android are roughly comparable. I expect Native Client will hold a strong edge in allowing close integration with web standards and web technologies. Android will probably continue to hold an edge in third-party application support and platform maturity.

Sugar-on-Native Client investigation

This post will describe the state of Native Client in general, based on week 2 of my original four week plan. In the next post, I'll link to my work so far, and compare the Native Client and the Android efforts. Recapping, the end goal of these explorations is a platform for the next generation of the Sugar learning environment.

To begin, the Native Client (NaCl) plugin is fairly mature in a number of areas. Version 0.2 of the NaCl SDK was recently released (a version number which substantiates the "fairly" in my previous sentence), and the NativeClient plugin is currently shipping in Chrome (versions 10 and 11), although you have to manually turn on a preference in the about:flags dialog to enable it. The NaCl toolchain is much more standard than the Android NDK toolchain I discussed previously, and the robust naclports tree shows that the patches required for NaCl ports of common packages tend not to be too evil. The Tcl interpreter and Qt tookit port demos show that fairly complex pieces of code can be deployed today on NaCl.

On the other hand, there are three main difficulties:

  1. The default NaCl toolchain uses newlib as its standard C library. This is consistent with Google's preference for BSD-licensed code in SDKs they provide to the public (see the discussion of Bionic in the Android SDK). However, there also exists a branch of the SDK which uses glibc. The glibc branch supports several additional features, like shared library support. However, it is unclear whether this will ever be a "supported" part of the SDK. If glibc does become supported, it is unlikely ever to be the only supported libc; the BSD-licensed newlib will need to remain available as an option. (Yes, the LGPL license of glibc shouldn't inspire such paranoia, but Google has elected not to undertake the education of all prospective third-party developers.)
  2. The naclports project, although fairly robust, is driven between the Scylla and Charybdis of compatibility. The goal is that all the code in naclports be buildable at all times on all three major platforms: Windows, Mac, and Linux. Further, it should support both x86_32 and x86_64 backends, and ideally ARM and pNaCl as well. It's auto-built against the latest SDK sources, but should also work on the latest released SDK. And with the addition of the glibc/newlib split discussed above, the possible build targets are multiplied further. Needless to say, keeping the tree building against such a large number of variants is not an easy task, and naclports is usually broken in some way. In practice, most developers seem to pay attention to some subset (say, x86_32/newlib/Linux host), but it's hard to push patches upstream without worrying about breaking some obscure target. It might be best to base future work on a proper package technology, like (say) dpkg-cross.
  3. In general, a lot of interesting NaCl development has occurred on branches that are not easily integrated. I've already mentioned glibc support, which is a toolchain branch; shared library support is on another branch that requires a new chromium plugin as well. At various times different means have been implemented to run NaCl binaries "natively" outside the sandbox (for example, in order to test some feature at build time, or auto-generate some piece of code via introspection). These efforts live on abandoned branches, while the "official" means to do this is incomplete. Similarly, a lot of interesting NaCl work used the now-abandoned legacy "NPAPI" plugin interface to interact with the browser. It was followed by the "Pepper" plugin interface, which was itself abandoned. Current work uses the Pepper2 browser plugin APIs, which (unfortunately) have not yet been implemented in non-Chrome browsers and continue to flux about. Many interesting browser interactions exist only in deprecated Pepper APIs, not having yet been built into Pepper2. ARM and pNaCl work also appears to be on unintegrated branches. There are a number of different gdb support strategies.

None of these difficulties is insurmountable—and in fact, some are side-effects of the desirable active development and productization of Native Client. To date I've done my work on the (more compatible) SDK v0.1 and the (more upstreamable) newlib library. So far newlib has not been a huge obstacle, and this basis allows my patches and ports to be more broadly useful. This might change in the future—certainly at some point we need to move to ARM and/or pNaCl for XO-3, which will probably require building chrome and the NaCl toolchain from scratch. At that point, it may be worth further exploring the non-mainstream branches.

How does the iPad "use the iPhone's GPS"?

A few months ago, a number of stories came out covering the iPad's remarkable-seeming ability to share the GPS of a tethered iPhone. Apple's latest location database FAQ confirms the suspicions I voiced at the time: there's no actual GPS sharing involved. Instead, Apple is using the simultaneous GPS and Wifi radios on your iPhone to "crowd-source" what I'll call a "skyhook" database (after the first company to publicly use the technique). This correlates Wifi base station identifiers with their GPS locations in real time -- including (most likely) the real time location of the "base station" created by the iPhone when it is in tethering mode. All nearby Apple devices use this database to compute their location (based on all visible wifi base stations). Since the nearby device sees the iPhone's "base station" and the iPhone is busily updating the position of that "base station" in real time (along with all the other base stations the iPhone can see), the iPad (lacking a GPS of its own) gains the apparent magical ability to compute a very accurate position for itself.

The real interesting part of this story involves user consent and privacy—do iPhone users generally know that their devices are registering their location in Apple's database in real time whenever tethering is turned on? Any device which can query Apple's location database for the MAC address of your iPhone can track the position of your iPhone whenever you are tethering. That's basically what the magical ability of the iPad/iPhone pair tells us. Did you know that?


Sugar-on-Android, week one

Last week I described a four-week plan to survey key technologies for One Laptop Per Child's forthcoming XO-3 tablet computer. Here I'll describe the results of the first week of work, which dove into Google's Android operating system. Warning: technical content ahead...

Basic design of Sugar-on-Android

  1. Cross-compile gobject/GTK/gobject-introspection/cairo/dbus for Android; distribute these key libraries as NDK libraries. This is what I spent most of my time on this week: I've managed so far to port libiconv, gettext, glib, pixman, freetype, fontconfig, cairo, libxml2, and pango. (Source code)
  2. Use cairo or OpenGL backends of GTK3 to render legacy Sugar activities directly to Android canvas.
  3. Modularize sugar; use D-Bus for inter-module communication. Interprocess communication mechanism is Android 'intents'; these can redirect to the web or the Android Market for missing dependencies. (Collabora reportedly already has a D-Bus implementation for Android.) Sugar components can also become Android Services.
  4. Implement Sugar Home/Groups/Neighborhood views and Journal as four separate Android App Widgets. These could also be implemented by providing a new Android home application, but I think the finer-grained modularity afforded by splitting these functions would yield a better design and make it easier to incorporate upstream improvements to the Android launcher.(Android Live Wallpaper is also similar in function, but not as good a fit.)
  5. The Sugar Journal becomes an Android "Content Provider", which stores/retrieves content for other Sugar activities. (There is special Android support for "collection-based Widgets" and Live Folders which may be helpful.)
  6. Use gobject-introspection to build a multi-language environment. Use JGIR to expose Sugar APIs to "native" Dalvik apps; use something like the Android Scripting Environment to expose Android native APIs to GIR languages (Python, JavaScript, C, etc).
  7. [opportunity] Use the Android port of OLSRd to implement a Neighborhood view. Alternatively, investigate AODV routing on Android and/or AllJoyn (which also requires root access, see pg 24-25 of the manual).

Key Benefits

  • Sugar is integrated into Android environment; use native Android education apps, or apps like Movie Studio which have no Sugar equivalents yet.
  • Android APIs and customization hooks are good, and provide a more-extensible framework for development.

Open challenges (general)

  1. The web integration story is cloudy. Java and JavaScript can call each other inside a bundled WebView widget, but this isn't supported in standard Browser app. Browser plugin interface would help.
  2. No good story for building 'native' Java/Dalvik or C apps on the device. Writing a simple Dalvik compiler would help. Dalvik specs are available, and people have written Dalvik compilers for toy languages.
  3. "View source" requests can be implemented as an Android 'intent' message, but no good story for implementing this functionality other than on a case-by-case basis in each activity.
  4. Although the Amazon Marketplace for Android indicates that it can be done, it appears that there is no "blessed" mechanism for creating .apk files on the device and installing them. (Android bug, discussion)

Current technical issues/bugs

  1. Cross-compiling for Android is currently a miserable experience. The Android NDK appears to have been put together by a team which had never seen a proper cross-compiler before. Since I only had a week for this exploration, I mostly kludged things together to get past this, but any serious work with Android should start by defining and upstreaming proper autoconf "target triplets" for Android-on-{ARMv5, ARMv7, x86} and building a proper cross-compiler. Then patches to various tools and libraries could start being upstreamed. Using the bespoke build system of the NDK is a non-starter. No serious obstacles here, just work to do.
  2. Xoom hardware is ARMv7, but Android emulator is ARMv5 only. Unfortunately, gdb is broken on the Xoom. So we're building for ARMv5 at the moment, so we can debug in the (slow) emulator.
  3. No good support for shared libraries may cause activity bloat. May be able to be worked around using the new Opaque Binary Blob (OBB) feature.
  4. Much existing code (fontconfig, gettext, gtk, etc) expects to read configuration files from the filesystem. Currently we are using the default fall-back configurations. OBB support may help here as well. There are a number of different storage APIs in Android, but none seems quite right.
  5. It would be nice to implement a ring-style XO home screen without completing replacing the android Launcher. No clear way to constrain app layout on home screen w/o completely replacing the Launcher. Is it worth hacking the Launcher source?
  6. Mesh on Android using OLSRd current requires root access. In order to run on unrooted Android devices, we need (a) proper power management for Ad Hoc mode wifi, (b) APIs to enable Ad Hoc mode, and (c) APIs to manipulate kernel routes.
  7. We're building libraries without thread support because Android's "Bionic" libc has an eccentric thread library. Linking with -lpthread fails because the thread functionality is bundled into -lc. Probably just providing an empty would help a lot.
  8. Some work has been done to build GNU libc for Android. This bloats activities even further, but might help ease library porting.
  9. Porting gobject-introspection will be painful because its makefiles are not set up for cross-compiling. Some steps want to run on the target hardware, which is difficult in the Android environment.

Bottom line

I can see how the whole Sugar stack can be put together on the Android platform. The hardest part is probably just setting up packaging and a good and repeatable build environment for the different components, and getting enough adoption of this that patches to support Android can be pushed upstream. Many of the important pieces can be developed in parallel (Theme, Journal, Mesh, Friends, Home, library porting, etc). A little early to tell how hard it will be to port existing Sugar activities to the new Python/pygobject/GTK3 framework.

Exploring New Technologies

Last Monday I rejoined One Laptop Per Child as Director, New Technologies. My mandate is hardware and software for the XO-3, OLPC's upcoming ARM-based tablet computer for education in the developing world. The new machine should be lower cost, lower power, more indestructible, more powerful, and potentially more expandable than ever. There are about two million machines in the XO-1 family (XO-1, XO-1.5) in the hands of kids today. The XO-3 will build upon this impressive foundation to reach further into the poorest and least-connected regions of the world.

I will kick-off my work with a series of four week-long sprints between now and eduJAM Uruguay to investigate a number of possible directions for the educational software stack on the XO-3 tablet. On the XO-1—series machines OLPC ships Sugar, an impressive collection of educational software developed by Sugar Labs. How can we best keep the best of Sugar while yanking the UI forward into a touch-friendly tablet world?

  1. This week (April 4-8) I'll begin by working on a port of the GTK3 UI library to Android. The GTK3 library contains touch support missing from the GTK2 library on which Sugar is currently based. The end goal here would be a full port of the Python/GTK-based Sugar APIs, running on something like the Honeycomb Android OS. Our existing educational activities could be ported to the new APIs without too much difficulty, but we'd largely use the existing Android OS facilities instead of the parts of Sugar concerned with low-level system management. To clarify: this is a preliminary exploration—we haven't decided to base the tablet software on Android (or anything else) yet.
  2. The next week brings a new direction. During the week of April 11-15 I will start porting Python/GTK3 to Chrome or ChromeOS via the Google NativeClient plugin. This path would result in activities which more fully integrate with web technologies—even in disconnected regions of the world. On desktop machines, Sugar activities could be run inside the Chrome browser, while ChromeOS (or another embedded OS running chrome/webkit) would provide the system management functions on tablet machines like the XO-3. As with the Android port, this is an exploration, not a definite software direction.
  3. The week of April 18-22 I hope to focus on mesh networking. This has a somewhat checkered history in our deployments; I hope to identify the remaining roadblocks and map a way forward to make this a flagship feature of the XO-3 software.
  4. The week of April 25-29 is for the existing Python-based Sugar codebase. In order to continue moving forward, it needs to migrate to GTK3, gobject-introspection, and some other key enabling technologies. I believe it would also benefit from language-independent APIs and better modularization to allow a more incremental migration path.

The following week is Conozco Uruguay and the Uruguay EduJAM where I'll present my progress on these initial exploratory projects and discuss the path ahead with the wider OLPC and Sugar communities. Clearly, a week each is not enough time to finish any of these projects! But the focused effort should help to better identify the promise, roadblocks, and challenges in each of these paths, which then in turn will help us to plan the future.

Taste, user experience, and engineering

A recent article on Nokia's internal culture contained this interesting quote:

Designers are also, by training and predilection, inclined to design for the usual, where engineers are taught a kind of rigor that compels them to account for, and overweight, low-probability events.

This does seem to me to often be a fundamental problem in not only interaction and UI design, but also internal programming APIs and interfaces. Good engineering is a clever balance; as Larry Wall has said: "Easy things should be easy, and hard things should be possible." An engineering mindset often fixates on the hard things (the "interesting part of the problem"!) and tries to make the hard things easy (or easier), at the risk of making the easy things hard. The end result is failure.

Truly elegant engineering involves finding a view of the problem where the hard parts of the problem disappear. We're not always fortunate enough to find that solution. In falling back to a practical/possible solution, we must be careful to ensure that we keep the easy things easy — it's fine if the hard things are difficult, so long as they are possible. Effort spent making the hard things easier is wasted if it makes the easy things harder. The goal is not a uniform mediocrity of design.

Improving Hunt Software/Improving Google Docs

There's been a lot of discussion about publishing and sharing the software that Mystery Hunt teams use to collaborate to solve puzzles. This is mostly misguided, IMO: teams are very different, and they organically grow solutions to fit their unique processes. On the other hand, an increasing number of teams (including my team, Codex), are building their collaboration software on top of Google services, especially Google Docs and Spreadsheets. Rather than trying to collaborate on One True Hunt Team Software, I think it would be far more useful (for all teams) to lobby for improvements to Google's services. These raise the bar for everyone, and indirectly benefit many other people with collaborative processes.

So here's my list of improvements I'd like to see in Google services:

  1. Integrating Docs and Spreadsheet. If we had an initial "sheet" of the spreadsheet with editable formatted text (not spreadsheet cells) we could actually do away with the wiki we use for capturing free form thoughts and links related to a puzzle.
  2. Integrating Spreadsheet chat, Google Talk, and Jabber. We could just use the chat in the spreadsheet if it were open and accessible, instead of creating our own per-puzzle chat rooms.
  3. Making publish and "setAnonymous" access available via APIs that actually work. We need to use Google Doc Script to do the setAnonymousAccess call, which is not exported via the otherwise-more-complete GData APIs, and drive a headless Firefox 2 instance via Selenium to get the publish bits enabled for the spreadsheet. That's ridiculous.
  4. Providing a way for Google Doc Scripts on a spreadsheet to export data more easily. We can use a Google Form to create a spreadsheet for a puzzle, but no easy way to provide a link to that spreadsheet on the page that results after form submission, or redirect from there.
  5. IIRC Google Talk support for multi-user chat is still barely supported. It doesn't use the standard Jabber protocols, for one. If this were a better supported/more standard service, we wouldn't have to run our own Jabber server.
  6. And, of course, the "next generation" of all this would integrate audio and video into the chat as well. Video is probably more useful, as it communicates human emotional cues. Audio isn't easily archived or searchable, and doesn't work well in crowded rooms, so it is less useful to us. But it would be great if we could actually see some/many/most of the particants in ringhunters, maybe little live video icons next to their faces.

Any further suggestions from other teams?

What's Wikileaks up to?

A recent article in the Economist points out that Wikileaks is not unique: modern network tools have made anonymous communication ubiquitous. You can't stop "wikileaks" by attacking Julian Assange alone. The article is incorrect, however, in claiming that anonymity is easy — in some sense anonymous leafleteers in Colonial America were better off. Bradley Manning currently sits in jail. Haystack was fundamentally flawed. There continues to be a role for organizations who desire to facilitate anonymous speech to identify and provide trustworthy and user-friendly tools and procedures.

Aaron Brady achieves a more fundamental insight by examining Julian Assange's aims. Assange's goal is to hobble "conspiracies", that is, the small cliques of power and secrecy embedded in most organizations, and he seeks to do this by causing them to fear information sharing. By this metric, Wikileaks seems to be succeeding. (Read Aaron Brady's essay for the details.)

But it's worth pausing to consider: are open organizations truly better? Is openness practically achievable? This is an organizational problem which was on the front burner at OLPC while I worked there: OLPC pledged an open development and governance model, but was continually charged with being closed, insular, and secretive in practice. We reorganized previously-internal mailing lists and pledged to conduct all important business on public archived lists. Yet there was continual backsliding. Sometimes private email was used merely to prevent embarrassment or confusion—to fact-check before making a public statement. Other times it was claimed that some measure of secret/private communication was a fundamental part of business or negotiation, necessary for interacting with external entities. In order to evaluate the latest components/plans/schedules of our partners, we had to sign NDAs. The secrecy requirements of the third-party then contaminated related discussions. In the end, even an organization with a goal of openness ended up embedding pockets of secrecy, which always threatened to grow and spread unless they were occasionally beaten back. Attempting to stand for open principles was often claimed to make OLPC "uncompetitive," as in: we couldn't hope to get the best deals/access to the latest components/whatever if we insisted on being open about everything.

The quest for openness in business seems to parallel the role of Wikileaks in national affairs. As with OLPC's business negotiations, we are being told that secrecy is an essential part of the diplomatic process, and that publishing internal cables hobbles America's ability to achieve its goals. The claim is that Wikileaks threatens to make America "uncompetitive."

Is this true? Openness is an ethical position, but not a black-and-white one. Very few people argued that OLPC (or America) should have no secrets — the debate was always "how many?" In practice if the desired answer was "as few as possible", there was always a Wikileaks-like need to continually drag private content to public forums in order to combat the creep of secrecy. Perhaps the same is true of governments.

Then again, over-reaching openness threatens individual privacy — where to draw the line? Must all our personal mistakes be made in public? Must all our national mistakes be made in public?

Airport searches.

For the record, my personal bugbear is the privacy implications of the new "advanced imaging" machines appearing at airports. But then again, I've distrusted supermarket loyalty cards and freeway FastLane programs, too -- my experience is that data which is collected will eventually escape your control (if you had any to begin with), and that no one is willing to offer a believable privacy pledge for such data (it would have to have 3rd-party audits for compliance, for example).

All that said, I just read a very reasonable article discussing the health impacts of the new scanners. I'm not going to play the alarmist card — ironically, the risks of injury from passing through a scanner are most likely about the risk of injury in a terrorism-related incident, that is to say extremely small — but it's prudent to admit honestly where risks are unknown, and to call the lie when deceptive arguments are used.

So let's not get all "ooh, scary, radiation" about this — quantum-physically speaking, everything is radiation at some wavelength — but it's worth keeping the risks in mind so you can make your own decisions, especially if you'd otherwise feel peer-pressured to "just do it". I'm just glad that as a nation we've apparently decided that this is where we're going to step up and draw the line, libertarians and liberals together. Contemplating our freedoms progessively and silently eroding away one by one is a far more worrying prospect.


Words With Pirates

I've caught the Words With Friends bug. Worse: the Words With Pirates subtype. (It's all the tile-placement and strategy fun of Words with less of the tedious racking your brain for obscure words; a more relaxing variant for when I don't want to think so hard.)

Today I discovered that I didn't actually understand the full word-creation rules for Words With Pirates. For the benefit of other similarly unenlightened folk, here's the accepted word list as a regular expression:


In more verbose format, these are all the words:

ar arg argh gar garg gargh gyar gyarg gyargh har harg hargh harhar harharhar hyar hyarg hyargh yar yarg yargh

In addition, an exclamation mark is always allowed at the end, and any non-zero number of r's may be substituted for any r.

Note that the words 'har', 'harhar', and 'harharhar', with optional exclamation marks at the end, are allowed. This is a little unusual, since the 15x15 grid should allow 'harharharhar' and 'harharharharhar' to also be played -- but these are not in the dictionary. Nevertheless, these oddball forms will probably prove useful to those stuck with excess a's.

For the benefit of the obsessive, there are 15 A's (worth 2 points), 9 G's (worth 3 points), 6 H's (worth 5 points), 28 R's (worth 1 point), 3 Y's (worth 10 points), and 3 !'s (worth 10 points), for a total of 64 tiles.


CoffeeScript and TurtleScript

Via reports on the OSCON 2010 Emerging Languages Camp, I recently discovered CoffeeScript, a very interesting "dialect" of JavaScript. The original idea for CoffeeScript seems to be to clean up the syntax of JavaScript, while preserving direct correspondence as much as possible. Over time, it seems to have grown more and more "neat features" which have increasingly-hairy desugarings into JavaScript — but the JavaScript translation of a CoffeeScript program is still very readable.

This has some relationship to my TurtleScript project, which also sought to clean up JavaScript to some degree. In TurtleScript I've tried to pare down as much of the language as possible, using the smallest number of syntactic forms and JavaScript features as possible, with the smallest possible parser/compiler/runtime system, inspired by Crockford's Simplified JavaScript.

CoffeeScript has some very elegant simplifications: for example, everything is an expression, which reduces the statement/expression syntactic distinction in C-like languages. Making the body of a function into an expression removes unnecessary return statements. Making for and while into expressions is a cute means to introduce (the power of) array comprehensions without additional syntax. CoffeeScript also has a nice way to express functions both with and without lexical this binding (a JavaScript skeleton in the closet).

Unfortunately, the full CoffeeScript language includes many many syntactic forms — even more than full JavaScript. Some of these can trivially be moved into a library, at a slight cost in compactness. While having varied syntax that precisely and concisely expresses programmer intent is certainly admirable, it makes the language harder to learn and, in my opinion, less elegant. For a scalable, learner-friendly language system I like something like NewSpeak more: a language whose goal is to grow smaller, not larger.

Adopting an IFRAME

Warning: heavy geek content.

Google recently rolled out a new Gmail feature: if you pop open a new little compose or chat window, and then close your main window, the small child window doesn't go away.

This is a pretty esoteric little tweak, but the underlying functionality is quite profound: in order to make this feature work, the entire document context (all the JavaScript responsible for running Gmail's UI) needs to get teleported from the main window out into the child window. For speed and memory reasons, you don't want to run a copy of the main code in the child window — no, you want to wait until just before you close the main window and then instantly teleport the guts of the main window over to the child. How's Google doing that?

In the browser model, separate windows are usually separate security contexts, safely sandboxed from each other. So this magic teleportation trick is also creating a wormhole between the different security domains. My curiosity was piqued, but Google (both blog and search engine) was strangely silent on how their new trick was pulled off.

Here's the story I eventually discovered. Google had long been thinking about a way to make this feature work. Their initial proposal was something called GlobalScript (or sometimes, "SharedScript"). This proposal met resistance and a new simpler solution was found: the "Magic IFRAME".

The guts are hidden inside bug 32848 in webkit's bug tracker. You put all of your application's good stuff inside an <iframe> element — we've guessed that already. You pass your child window a copy of that IFRAME, something like:

function doSomethingCoolThatNeedsANewWindow() {
     var childWin =;
     childWin.onload = function() {

Now, the crux: when your main window is about to close, you just adoptNode the shared <iframe>:

// adoptNode in this case does removeChild() internally
// but does not unload the content

Voila! This used to completely unload and reload the iframe, erasing the existing application context, but with this one small hack Chrome (and now Safari, too) suppresses the reload and allows the untouched <iframe> context to teleport over to the child.

This doesn't work on Mozilla yet. And it's a pretty ugly hack, tweaking the behavior in just this one narrow case. (And Mozilla is a little bit cranky about adoptNode() being used without an prior importNode().) But this hack also allows work-arounds for two other long-standing iframe-reparenting "bugs". It suggests that <iframe> is now the <module> tag Crockford wanted, especially now that the <iframe> can be sandboxed in various ways as well. By putting each piece inside an <iframe> you can now build a robust module system for browser JavaScript.


Log in