picture home | pixelblog | qt_tools

omino code blog

We need code. Lots of code.
David Van Brink // Thu 2011.08.18 20:25 // {javascript}

Spec from Code, and State Machines

Spec from Code??

I’ve worked in an organization where the expected development flow was to produce a Microsoft Word document, check it in to revision control, have others comment on it (in revision control), resolve comments, and then, finally, write code.

After coding, you were supposed to go back and revise the document to match the actual outcome. This rarely happened.

A certain amount of design and review, and, alas, yes, even consensus-building can be useful, but, call me old-fashioned, but I don’t think uSoft Word in Perforce is ideal for this. (I’ve also worked in groups that used almost no written designs, and a lot of conversation, and produced long-lived excellent products.)

You know where I like to do my editing? No really, guess. That’s right. In Eclipse. (Well, that’s my IDE of choice & I’m sticking to it.)

And you know where I like my specs to come from? Ideally, as a product from the actual, running code.

Specs are specs, but code is reality.

Isn’t that crazy?

Here’s two familiar examples of this. First: JavaDoc. Yes, your spec comes out as an HTML file, which you edit in the IDE.

A slightly more interesting common example is a command-line options parser. The options parser typically describes something about the allowed values of the switches, which are required, and other “metadata”. This information is used runtime validity testing, and also to produce your –help listing. Spec from code!

State Machines

State machines are cool. Tricky interactions can sometimes be more clearly phrased as a state machine. Instead of having a jillion little booleans and flags, you have one main state, and maybe some ancillary variables.

You process an “event”, and that may change the “state”, and cause other things to happen, too.

A colleague came across Jake Gordon’s JavaScript Finite State Machine “microframework” recently. Good stuff. Gives a clear way to specify a state machine as a JavaScript data structure, like so:

    var events = [    
        { name: 'warn',  from: ['green'],           to: 'yellow' },
        { name: 'panic', from: ['green', 'yellow'], to: 'red'    },
        { name: 'calm',  from: ['red'],             to: 'yellow' },
        { name: 'clear', from: ['red',   'yellow'], to: 'green'  },

The framework then gives you callbacks like ongreen() and oncalm() where you can do your application-specific work.

I was looking at it, and thought, Hey! That’s enough information to produce some documentation!

Fsm demo

The picture above is from a “DOT Language” graph, and was rendered by GraphViz. The source code for the graph is:

graph fsm {
   green -> yellow  [label="warn"];
   green -> red  [label="panic"];
   yellow -> red  [label="panic"];
   red -> yellow  [label="calm"];
   red -> green  [label="clear"];
   yellow -> green  [label="clear"];

You can see the connection, yes?

And, lastly, here is the JavaScript which turned Jake’s FSM Description structure into a DOT file:

function toDotty(events) 
   var result = "";
   result += "digraph fsm {\n";

   for(var i = 0; i < events.length; i++)
      var event = events[i];
      var name = event.name;
      var to = event.to;
      var fromList = event.from;

      if(typeof(fromList) == "string")
         fromList = [fromList];

      for(var j = 0; j < fromList.length; j++)
         var from = fromList[j];
         var aTransition = {from:j, to:to, name:name}
         result += "   " + from + " -> " + to + "  [label=\"" + name + "\"];\n";
   result += "}\n";
   return result;


Doing design work up front is important. But at some point, the code acquires a richer life than your predesign spec. After that, in a very real sense, the only spec is the code, itself. If you can force it to document itself, to reveal aspects of itself at appropriate levels of abstraction, you can continue to understand it.

oh, i dont know. what do you think?

(c) 2003-2011 omino.com / contact poly@omino.com