[closer-devel] ContextL design question...

Pascal Costanza pc at p-cos.net
Sun Feb 26 15:07:41 UTC 2006


Hi everybody,

I am currently working on providing meta-level access to layer  
activation/deactivation in ContextL. As expected, this turns up a  
number of related questions, and one of them seems to be very  
fundamental. Before I make a solitary decision here, I would like to  
hear other people's opinions, especially from those who have already  
played around with ContextL.

Here we go: Currently, a layer is referred to only by name. So if we  
define a layer like this:

(deflayer employement)

...we activate it later on by saying that:

(with-active-layers (employment)
   ...)

In other words, layers are singletons. Until now, this doesn't matter  
much, because we cannot yet associate state with layers and cannot  
define relationships between layers. One of the goals of providing  
meta-level access to layer activation/deactivation is that we can  
start to define such relationships, like mutually exclusive layers,  
or layer dependencies, etc.

Those of you you have taken a look at the implementation of ContextL  
know that layers are internally implemented as classes. So a layer  
definition like (deflayer employment) is actually something like:

(defclass layer ()
   ()
   (:metaclass ...))

(Except for the fact that there is a provision for avoiding name  
conflicts with classes, among other things.)

Since layers are based on classes, it is actually relatively  
straightforward to allow for inheritance between layers. I have  
played around with a few toy examples, and this seems to make sense.  
Nick Bourner has sent me an example (in private) that could partially  
be modeled with such layer inheritance. Assume you have an output  
layer and different ways to perform output. This could roughly be  
modelled like this:

(deflayer output)

(deflayer html-output (output))

(deflayer xml-output (output))

(deflayer json-output (output))

So the idea is that the output layer defines the common functionality  
for generating output, while the other output layers define more  
specific functionality. Since the specific output layers inherit from  
output, common code can indeed be factored out. (The other goal is to  
ensure that at most one of the specific output layers is active at  
the same time.)

Now comes the actual design question: If we stick to the fact that  
layers are singletons, what we actually get here is a kind of  
prototype-based object model. For example, in my toy examples, I  
needed to define slots for layers which should be inherited by  
sublayers. For example:

(deflayer output ()
   ((grouped-layer-root :initform 'output
                        :reader grouped-layer-root)
    (grouped-layer-default-layer :initform 'html-output
                                 :reader grouped-layer-default-layer)))

Due to inheritance between layers, this would mean that, say,  
(grouped-layer-root (find-layer 'xml-output)) would correctly yield  
'output. In other words, we get the kind of inheritance of slots as  
with :allocation :class in standard classes.

The alternative route to go would be to leave the prototype-based  
model, but instead go for a class-based model. Then layers would  
"just" be ordinary classes. However, for layer activation/ 
deactivation, one couldn't just refere to the names anymore. Instead,  
one would have to create instances of layers, as follows:

(with-active-layers ((make-instance 'employment))
   ...)

This would allow us to have multiple instances of the same layer, and  
the inheritance model (slots & code) would be the same as in plain CLOS.

My subjective opinion is to keep the prototype-based model.  
Currently, I don't see any uses for the class-based model - i.e., I  
don't see a use for having multiple instances of the same layer. At  
the same time, the prototype-based model seems quite attractive  
because of its relative simplicity of use. In case one really needs  
multiple instances of the same layer, this could later on be achieved  
as in "real" prototype-based languages, by inheriting from existing  
prototypes and allowing for anonymous layers. But that's "just in  
case"...

So, any opinions?


Cheers,
Pascal

-- 
Pascal Costanza, mailto:pc at p-cos.net, http://p-cos.net
Vrije Universiteit Brussel, Programming Technology Lab
Pleinlaan 2, B-1050 Brussel, Belgium







More information about the closer-devel mailing list