VisiCalc-like development in Lisp
Monday, January 26, 2004
As I mentioned in an earlier posting, the Denver Area Lisp Users Group is having a double-banger meeting in February. Kenny Tilton will be giving an overview presentation on Cells (an extension to CLOS in Common Lisp that allows one to code Lisp applications that dynamically react to changes in slot values, much like the way spreadsheet cells behave) and Cello (a GUI framework built on top of Cells) on Saturday, February 7th. This will be followed up with a workshop on Monday, February 9th where Kenny will provide a hands-on tutorial. I'll be posting an official announcement sometime in the next week or so; however, in order to whet appetites, I asked Kenny to provide some additional information on what's been happening recently with Cells/Cello. Here's his latest report:
"I am now working full time on Cello, getting ready to relaunch my educational software business. Screenshots from the mothballed application (based on a Cello precursor which was MCL/OS9-specific) are here:It is sometimes difficult for people to grasp what exactly Cells is and why is it different from similar approaches. In an email exchange I had with someone about Cells, I was asked how Cells differs from standard Listener-based frameworks (such as Swing in Java). In reply, I said:
http://www.tilton-technology.com/Arith_top.html
Cello has been given a couple of awesome bionic upgrades over the last two weeks. The background here is that I am using OpenGL as my graphics engine, first for portability, second for awesome capabilities and performance graphics-wise. The first upgrade was some FFI work to bolt in FTGL, a superb implementation of TrueType fonts for OpenGL. Without this Opengl is awful at text, with it we have bitmap, pixmap, texture, outline, polygon, and extruded polygon fonts. Pixmaps and texture fonts are anti-aliased. And gorgeous.
The second upgrade went in last night: FFI extensions to pull in the astonishing ImageMagick library, which displays JPEG, GIF, BMP, MPEG, AVI and eighty (!) other graphic formats.
Add Cello and 3D and, well, this is not your father's GUI. :)
On the portability front, Thomas Burdick is striving as we speak to modify CMUCL/SBCL as necessary to support callbacks into Lisp from C. Cello (for now) gets portable window management from Freeglut, which works via so many application callbacks.
Thomas is hoping to adopt Cello as his GUI on OS X, having been a big Garnet fan, and I need it to do my ed software for the Mac, so OS X should be online shortly. Note that even without SBCL/OS X, a Cello port based on MCL/LW/ACL and (probably) Apple's own Quartz-inside GLUT would be possible."
"I'd say that the difference is in that it is a standard feature of every "class" that is defined in Cells. At any stage, you can create a "listener" that responds to changes without modifying the class."However, not being an expert on Cells, I also asked Kenny to give a better explanation of how Cells differs from standard Listener-based approaches and what you do when you want to create new kinds of events that react to a change in a cell. Here is his reply:
I would have to go study up on Swing and addListener to give an accurate reply, but being a lazy fellow I'll just wing it. :) First of all, I /do/ cite the Observer Pattern as prior art when discussing Cells. In TCL it was Subscribe/Notify. What these and apparently the Swing Listener mechanism have in common with cells is the general idea of the reliable propagation of state change throughout an application model. Now for some guesswork:It'll be interesting to see/hear some more when Kenny comes to town.
"new kinds of events" suggests to me that the Swing listener scheme involves a lot of what I would call exposed wiring. This is what I saw in the GoF Observer Pattern. "listening" is (a) between instances and (b) requires the developer to write code which (1) says "I am listening to you", (2) "dear listeners, this event just happened", and (3) "whoa, this event just happened to this thing to which I am listening". Also (4) "I am no longer listening to you".
Cells is (i) slot-oriented (a slot being CLOS-ese for "data member" if I have the C++ terminology correct) and (ii) transparent/declarative. There are no "events" as far as the application developer is concerned. Folks usually get confused by this analogy, but as strange as it seems, one simply codes a spreadsheet-like rule (using the full power of the language at hand, be it CL or Java or Python) for the slot of an instance and the engine sees to it that the slot value stays current as other slots used by the rule (well, those that are also cells, but almost all my slots end up cells in real apps) change. So all the wiring is hidden: dependencies are between slots (not instances) and they are identified and tracked automatically by the engine. Like I said, it feels just like VisiCalc when I am programming, and yes, it /is/ a paradigm shift because it took even me its developer quite a while to get into the swing <g> of things.
The upshot is that one is forced to abandon the imperative approach and live within the declarative paradigm. Why? Because once anything starts working thru this engine, anyone who wants to play along must submit to the engine. The good news is that--as always--declarative beats imperative hands down. It is more reliable and more fun. It also decomposes complexity, which is easiest to understand if one has ever developed an intense spreadsheet.

