[closer-devel] interesting contextl use-case

Pascal Costanza pc at p-cos.net
Tue Jun 12 18:02:38 UTC 2007


On 12 Jun 2007, at 11:36, Attila Lendvai wrote:

> hi!
>
> we would like to add new slots to a class when being inside a layer.
> the need comes when running some algorithm to calculate some new
> properties of some instances. the usual solution is to set up a
> hashtable, and add the extra property value in that hashtable.
>
> what we would like to do is to define new slots for a class but only
> in a given layer. so make-instance'ing that class when the layer is
> active should return instances with the extra slots.
>
> i'm not sure if this is already possible, but a possible
> implementation would be to delegate make-instance to
> make-layered-instance or make-instance-using-layer, then consult the
> layer context and as needed return an unnamed subclass of the actual
> class that contains the extra slots.
>
> thoughts?

I don't fully understand what you are asking for, but let me make  
some guesses. ;)

The basic functionality, as far as I see it, is already available:  
You can give partial definitions for the same layered class  
associated with different layers. This effectively allows you to  
define slots that are only visible when some layer is active. The  
basic approach looks like this:

(define-layered-class my-object ()
   ((foo :initarg :foo :layered-accessor foo)))

(deflayer l1)

(define-layered-class my-object :in-layer l1 ()
   ((bar :initarg :bar :layered-accessor bar)))

The effect of this definition is as follows:

- The slot foo is always visible.
- The slot bar can only be accessed via the accessor methods bar and  
(setf bar) when the layer l1 is active.
- If you don't initialize a slot with a keyword argument (:foo  
or :bar) it will remain unbound (unless it has an :initform).

In ContextL, the various slots from partial class definitions that  
contribute to a layered class are always allocated in instances of  
that class. However, as in CLOS, you always have control over whether  
they are actually bound or not. I have thought about making  
allocation of such slots variable, but I have decided against because  
(a) I don't expect the memory overhead to be substantial enough to  
warrant a more complex solution and (b) it's always easy to add  
optional slots with another metaclass that uses hashtables in the  
background (one of the standard CLOS MOP examples). It should be  
relatively straightforward to add this to ContextL at the user level.

BTW, the restriction of access to slots coming from specific layers  
is only in effect for accessor (reader and writer) methods. slot- 
value and (setf slot-value) can always access slots, no matter what  
layer is active, because they are the low-level access mechanisms  
that are important for, for example, debuggers, inspectors, etc.

If you indeed want to ensure that, based on the set of currently  
active layers, instances of a different class are created such that  
the slots from other non-active layers are definitely not present,  
then you can achieve this by implementing your own abstraction on top  
of CLOS / ContextL. Just implement your own layered function for  
creating instances, say create-instance, then you can define layered  
methods on it that change what kind of instance is actually created.  
It could have been possible to add such functionality to make- 
instance from within ContextL - however, modifying make-instance that  
way is probably not a good idea because CLOS implementations  
typically try to optimize instance creation as heavily as possible.  
Whenever you define methods on make-instance, there is a chance that  
you slow down the overall CLOS runtime. (That's just a guess, though,  
I could be wrong here.)

I have probably not quite got the gist of what you actually want, but  
it's now your turn to clarify my misunderstandings. ;-)


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