[First published February 11, 2008 on blogspot.com.]
[We may as well get this out of the way, an explanation of my pet project Cells, the kind of thing I’ll be sitting in a rocking chair twenty years from now mumbling how the CIA stole it from me but they don’t have the latest version I have that in a floppy disk here in my shirt pocket.]
In the text that follows, [xxx] signifies a footnote named “xxx” and listed alphabetically at the end.
Cells is a mature, stable extension to CLOS[impl] allowing one to create classes whose instances can have slot values determined by instance-specific formulas. It is useful for any application involving an interesting amount of long-lived state and a stream of unpredictable inputs. Two examples are any GUI-based application and a RoboCup client (trying to simulate a soccer player given a stream of sensory data fed it by the game server).
For example, in a text editor application we might have (condensed, and with the symbol “.w.” macroexpanding to code that returns the relevant window)):
:enabled (c? (bwhen (f (focus .w.))
(and (typep f 'text-widget)
Translated, the enabled state of the Cut menu item follows whether or not the user is focused on a text-edit widget and whether they have in fact selected a range of text, the trick being that nil is treated as false by (decent) Lisp dialects.
Meanwhile, the selection-range rule might be:
(c? (if (mouse-down? .w.)
(bwhen (c (mouse-pos-to-char self (mouse-pos .w.)))
(list start c)
(setf start c)))
(setf start nil))))
Now the only imperative code needed is some glue reading the OS event loop converting raw mouse down and mouse move events into window attributes such as mouse-down? and mouse-pos. The desired functionality is achieved by declarative rules which (like selection-range above) are entirely responsible for deciding the selection range.
A final trick comes from slot observers. Suppose we are thinly wrapping a C GUI and…