Saturday, 21 July 2007

Closures + Lambda < CLOS

There's a blog post floating around the web[1] on how Closures + Lambda make up all the OO programming tools you'll ever want or need. Now this is a long running theme[2] in the Lisp family and really is a testament to how flexible Common Lisp (or any other language which shares these traits) is

.... however ....

the majority of these are for pedagogical purposes[3] and should never be seriously
compared with a fully fledged object system. It's seems to be in vogue to consider
CLOS elephantine[4] and complex but the truth is that at the surface CLOS is wonderfully simple.

We have classes with slots (read instance variables) created with defclass, we create
instances of these classes with make-instance. We access (and change) the slots of these
instances using slot-value and create methods for the classes using defmethod.

Simple, yes? Not complex or elephantine, Yes?

You can read more of course (all in the CLHS) and discover the object initialization protocol
and how the classes of objects can be changed on the fly, you can find out how to customize
the initialization of your classes and add accessors to your slots.
You can dig deeper and you'll discover the MOP and discover how to change the behaviour of
slot access and class definition.

But remember that you do not need to understand any of this in order to
define classes, create instances, access slots and define methods!

So next time you are rolling your own Object System because someone considers CLOS too slow,
or too large, stop and give CLOS a try, you may just like it.

[1] : See here and here .
[2] : And is implemented in PAIP and On Lisp among others.
[3] : For a full OO implementation in CL see KR which is a prototype based object system with valuepropogation.
[4] : Or big, slow[5] or klunky
[5] : This myth has officially been debunked.


green said...

About the "CLOS is slow" issue -- you mention that "this myth has been debunked", so I'd like to know the source. Please don't make claims about performance without citing any experiments.
At least the implementations I use (CMUCL, Clisp and SBCL) are not very fast when accessing CLOS objects. What I did was to access objects, structures and arrays repeatedly in a simple test. CLOS was very slow.

Try to write some benchmark code comparing access to instances of CLOS objects, aceess to structures and access to plain arrays. Also, try to use plain functions, generic functions and methods on all structures. On different Lisp implementations. Then post the times.

In my opinion, it would be good for Lisp and for the Lisp community if any problems (for example, CLOS slowness) were made clear, so we an do something about them (for example, if everybody concluded that CLOS is inherently slow because of its flexibility, then someone could come up with a lightweight alternative).

green said...

BTW -- I made the tests because I was considering switching from C++ to Lisp. In C++, I do acess objects directly inside loops (and this is number crunching, it *needs* to be fast). In Lisp I have to extract arrays from inside the object, and then traverse them if I want the code to be fast.

Jon Harrop said...

Indeed. I asked for some evidence of CLOS not being slow on c.l.l and the only response was an article from many years ago saying that CLOS had gotten faster.

From the benchmarks I've seen, CLOS is extremely slow.