» Sunday, 29 April A.D. 2007

refactoring state machines

I have some code that boils down to a large state machine. I had written this as one structure holding a keyword denoting the state we are currently in as well as a bunch of other required data. The driver, then, looked like:

(defun driver (state)
  (loop
    (ecase (state-of state)
      (:state1 ...)
      (:state2 ...)
      (:state3 ...)
      ...)))

The bodies of each case were simply calls to a state-specific function that did the necessary work and set STATE-OF appropriately.

This morning, I had an epiphany. I could use the name of the individual state-specific functions as my STATE-OF, which reduces my driver to:

(defun driver (state)
  (loop (funcall (state-of state) state)))

I think KMP once pointed out in comp.lang.lisp that instead of using a hashtable for some things, you might stuff information onto the symbol-plist--basically letting the reader do your hash lookup for you. This is a variation on the same theme.

posted by Nate @ 4:59PM