I’ve written before about Eric Raymond’s (esr) UPSide project that aims to build an open source UPS that has reasonable performance and sensible operation. Esr’s latest post is especially interesting to me because it uses one of my favorite techniques: having programs write programs.
The control logic for UPSide features a state machine that listens for events—loss of AC power, say—and performs the required action based on the current state of the system. The traditional way of documenting state machines (at least for reasonably sized ones) is with a state transition diagram. Here’s the state transition diagram for UPSide. It’s straightforward and easy to understand. Spend a couple of minutes with it and you’ll understand the broad view of how UPSide works.
The diagram itself is produced with the Graphviz dot
language. Dot
is pretty simple to use but there’s a lot of boilerplate and it can be hard to read. Rather than deal with the grunt work, esr wrote the states and their transitions (what he calls “actions”) in a pseudocode that he shows at the bottom of the state diagram. I almost always do something like this when I’m dealing with a nontrivial dot
graph because it lets you think about the diagram you’re producing rather than the dot
language.
Esr took this one step further. He realized that he could use that pseudocode to generate the Go source code for the state machine too. That’s a big win because it’s much easier to understand and debug the state diagram then it is the Go code. Indeed, within an hour of posting the diagram, people were already reporting a bug in the state machine. Did you see it? Fixing it was easy: Esr simply changed a single action in the pseudocode and regenerated the diagram and Go code.
Generation of the diagram and code are both done with this small Python program. Everything that’s needed—including the pseudocode—is contained in the source for that program. It’s easy to understand and worth studying if this technique is new to you. Or even if it isn’t, you may learn some useful ideas.
Esr talks about using this technique in this UPSide progress report.