From: Peter Seibel
Subject: Uses of :allocation :class?
Date: 
Message-ID: <m3isdzsaqm.fsf@javamonkey.com>
Anyone have any favorite idioms involving :allocation :class slots. I
understand how they work but am trying to decide how much I want to
talk about them in my book--there is a fair bit of potential to
confuse Java and Python programmers since they look, at first glance,
to be Lisp's analogue to static or class variables in those languages
but since Lisp's :class slots can only (ignoring the MOP) be accessed
through an instance of the class they actually can't be used they way
their seeming counterparts in Java and Python typically are. So if I
bring them up I have to explain why they're *not* the same which is
only worthwhile if there's some payoff in terms of cool coding idioms
that they figure in. Thanks.

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp

From: Ari Johnson
Subject: Re: Uses of :allocation :class?
Date: 
Message-ID: <5o0yc.9892$E03.1414@fed1read01>
Peter Seibel wrote:
> Anyone have any favorite idioms involving :allocation :class slots. I
> understand how they work but am trying to decide how much I want to
> talk about them in my book--there is a fair bit of potential to
> confuse Java and Python programmers since they look, at first glance,
> to be Lisp's analogue to static or class variables in those languages
> but since Lisp's :class slots can only (ignoring the MOP) be accessed
> through an instance of the class they actually can't be used they way
> their seeming counterparts in Java and Python typically are. So if I
> bring them up I have to explain why they're *not* the same which is
> only worthwhile if there's some payoff in terms of cool coding idioms
> that they figure in. Thanks.

First off, I found (class-prototype 'classname) to be very useful in 
alleviating any confusion I, as a C++ programmer, had about :allocation 
:class slots.

The specific place I used this in my 'exercise some Lisp knowledge' test 
project, which was a MUSE server, was in keeping a hash-table on the 
class 'player' so that no two players could have the same name or alias, 
whereas objects of other types can have the same name just fine.

The neat thing was that this project got slightly farther in some ways 
than when I wrote it in C++ several years ago, and it only took me about 
a week, putting in about an hour or two a day.  Thanks, Jeritol^WLisp! ;)
From: Raymond Toy
Subject: Re: Uses of :allocation :class?
Date: 
Message-ID: <sxdsmd31js5.fsf@edgedsp4.rtp.ericsson.se>
>>>>> "Peter" == Peter Seibel <·····@javamonkey.com> writes:

    Peter> Anyone have any favorite idioms involving :allocation :class slots. I

I don't have a favorite idiom, but I did use :allocation :class slots
on a particular project.  Not sure what I did was really right, but it
seemed to work how I wanted.

I had a base class that had the default slot allocation.  Then there
were several subclasses derived from the base class.  In these
subclasses, I made the slot :allocation :class because this slot was
the same for all instances of the subclass.  I didn't want to use
standard allocation because the value was quite large (2K words or
more), and I expected to have a fair number of instances.

I could have just made the slot value a global constant and had the
slot point to the global constant, I suppose, but that kind of broke
the connection between the object and what data it carried.  

Besides it let me play around with something new. :-)

Ray
From: Peter Seibel
Subject: Re: Uses of :allocation :class?
Date: 
Message-ID: <m3ekons7hy.fsf@javamonkey.com>
Raymond Toy <···@rtp.ericsson.se> writes:

>>>>>> "Peter" == Peter Seibel <·····@javamonkey.com> writes:
>
>     Peter> Anyone have any favorite idioms involving :allocation
>     Peter> :class slots. I
>
> I don't have a favorite idiom, but I did use :allocation :class
> slots on a particular project. Not sure what I did was really right,
> but it seemed to work how I wanted.
>
> I had a base class that had the default slot allocation. Then there
> were several subclasses derived from the base class. In these
> subclasses, I made the slot :allocation :class because this slot was
> the same for all instances of the subclass. I didn't want to use
> standard allocation because the value was quite large (2K words or
> more), and I expected to have a fair number of instances.

Right. That was one idiom I identified--saving space while keeping the
SLOT-VALUE interface. I.e. when the value is essentially determined by
the class of the object but different classes may have different
values and there are going to be many, many instances of each class,
we can save some space by using a class-allocated slot. But it seems
as soon as you start changing the value of a class allocated slot
you're off in weird action-at-a-distance land that is going to be hard
to reason about.

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: mikel
Subject: Re: Uses of :allocation :class?
Date: 
Message-ID: <Dg0yc.155$tM7.15@newssvr27.news.prodigy.com>
Peter Seibel wrote:

> Raymond Toy <···@rtp.ericsson.se> writes:
> 
> 
>>>>>>>"Peter" == Peter Seibel <·····@javamonkey.com> writes:
>>
>>    Peter> Anyone have any favorite idioms involving :allocation
>>    Peter> :class slots. I
>>
>>I don't have a favorite idiom, but I did use :allocation :class
>>slots on a particular project. Not sure what I did was really right,
>>but it seemed to work how I wanted.
>>
>>I had a base class that had the default slot allocation. Then there
>>were several subclasses derived from the base class. In these
>>subclasses, I made the slot :allocation :class because this slot was
>>the same for all instances of the subclass. I didn't want to use
>>standard allocation because the value was quite large (2K words or
>>more), and I expected to have a fair number of instances.
> 
> 
> Right. That was one idiom I identified--saving space while keeping the
> SLOT-VALUE interface. I.e. when the value is essentially determined by
> the class of the object but different classes may have different
> values and there are going to be many, many instances of each class,
> we can save some space by using a class-allocated slot. But it seems
> as soon as you start changing the value of a class allocated slot
> you're off in weird action-at-a-distance land that is going to be hard
> to reason about.

Depends on what you mean by changing it. Presumably you mean SETF of the 
slot. On the other hand, lots of applications manage pools of resources 
(e.g. file-descriptors, threads, reusable chunks of memory, etc.) for 
various performance and robustness reasons. If you're using a pool, a 
reasonable way to manage it could be to create classes with 
class-allocated slots set up so that the pool is initialized the first 
time an instance is created. Then every instance is guaranteed to get a 
reference to the same pool, and pool-management stuff can be done by 
applying functions to the value of that slot. Those functions might 
change the pool--allocate or deallocate a resource, for example---but 
the resulting behavior should not be particularly mysterious.
From: Peter Seibel
Subject: Re: Uses of :allocation :class?
Date: 
Message-ID: <m3659zs4gm.fsf@javamonkey.com>
mikel <·····@evins.net> writes:

> Peter Seibel wrote:
>
>> Raymond Toy <···@rtp.ericsson.se> writes:
>>
>>>>>>>>"Peter" == Peter Seibel <·····@javamonkey.com> writes:
>>>
>>>    Peter> Anyone have any favorite idioms involving :allocation
>>>    Peter> :class slots. I
>>>
>>>I don't have a favorite idiom, but I did use :allocation :class
>>>slots on a particular project. Not sure what I did was really right,
>>>but it seemed to work how I wanted.
>>>
>>>I had a base class that had the default slot allocation. Then there
>>>were several subclasses derived from the base class. In these
>>>subclasses, I made the slot :allocation :class because this slot was
>>>the same for all instances of the subclass. I didn't want to use
>>>standard allocation because the value was quite large (2K words or
>>>more), and I expected to have a fair number of instances.
>> Right. That was one idiom I identified--saving space while keeping
>> the
>> SLOT-VALUE interface. I.e. when the value is essentially determined by
>> the class of the object but different classes may have different
>> values and there are going to be many, many instances of each class,
>> we can save some space by using a class-allocated slot. But it seems
>> as soon as you start changing the value of a class allocated slot
>> you're off in weird action-at-a-distance land that is going to be hard
>> to reason about.
>
> Depends on what you mean by changing it. Presumably you mean SETF of
> the slot. On the other hand, lots of applications manage pools of
> resources (e.g. file-descriptors, threads, reusable chunks of memory,
> etc.) for various performance and robustness reasons. If you're using
> a pool, a reasonable way to manage it could be to create classes with
> class-allocated slots set up so that the pool is initialized the first
> time an instance is created. Then every instance is guaranteed to get
> a reference to the same pool, and pool-management stuff can be done by
> applying functions to the value of that slot. Those functions might
> change the pool--allocate or deallocate a resource, for example---but
> the resulting behavior should not be particularly mysterious.

That's a good point. I guess that's particularly useful if the "pool"
is just a list that items are PUSH'd on and POP'd off of--essentially
the class object provides the layer of indirection so that all
instances share a place where the current head of the pool is stored.
As the identity of the pool (in the EQ sense) changes, all instances
will see the change. The same effect could be achived by simply
creating an object that holds the head of the list but whose identity
never changes and give every instance of the class a reference to that
object. So it still seems to boil down to mostly a savings of
space--because every instance already has a reference to the class
object, we save space in each instance by not having to have another
reference to some distinct mutable object.

Anyway, I'll have to ponder this some more. Thanks.

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Raymond Toy
Subject: Re: Uses of :allocation :class?
Date: 
Message-ID: <sxdbrjr15l4.fsf@edgedsp4.rtp.ericsson.se>
>>>>> "Peter" == Peter Seibel <·····@javamonkey.com> writes:

    Peter> Right. That was one idiom I identified--saving space while keeping the
    Peter> SLOT-VALUE interface. I.e. when the value is essentially determined by
    Peter> the class of the object but different classes may have different
    Peter> values and there are going to be many, many instances of each class,
    Peter> we can save some space by using a class-allocated slot. But it seems
    Peter> as soon as you start changing the value of a class allocated slot
    Peter> you're off in weird action-at-a-distance land that is going to be hard
    Peter> to reason about.

Yes, that is hard.  For my particular application, the slot was really
a constant.  I didn't enforce it though, but I suppose I could have
added a slot writer function that caused an error if someone tried to
write it.

I did have some issues with this, though, when I recompiled and
reloaded the code.  Sometimes, existing instances would cause strange
errors.  I never bothered to figure out if I messed up or if the CLOS
implementation messed up, or what the real problem was.  It was easier
to just quit and reload the fasls.  The process wasn't carrying much
state, so I didn't really lose anything.

Ray
From: Rahul Jain
Subject: Re: Uses of :allocation :class?
Date: 
Message-ID: <87u0xglj69.fsf@nyct.net>
Peter Seibel <·····@javamonkey.com> writes:

> Anyone have any favorite idioms involving :allocation :class slots.

DISCRETIONARY-HYPHENs in DefDoc.

(defclass discretionary-hyphen (discretionary-break)
  ((pre-break-elements #-pcl :type #-pcl (cons * null)
                       :reader pre-break-elements
                       :documentation "Initialize this with the 'HYPHEN-CHAR initarg.")
   (post-break-elements :type null :allocation :class)
   (no-break-elements :type null :allocation :class)
   (break-penalty :type null :allocation :class)))

http://www.common-lisp.net/cgi-bin/viewcvs.cgi/DefDoc/src/elements/basic-elements.lisp?rev=1.2&cvsroot=defdoc&content-type=text/vnd.viewcvs-markup

This way I don't bloat the instances with data that won't vary.

-- 
Rahul Jain
·····@nyct.net
Professional Software Developer, Amateur Quantum Mechanicist
From: Toomas Altosaar
Subject: Re: Uses of :allocation :class?
Date: 
Message-ID: <3ef90b62.0406121415.3d4574f9@posting.google.com>
I struggled with :allocation :class for several years using it for
reasons similar to the ones cited by the gentleman from LM Ericsson,
i.e., mainly storing static data structures efficiently.

In my situation I needed a private slot allocation for every class,
and not shared via inheritence as found in the spec, see Steele, CLTL,
2nd edition, p. 824. So my solution was to patch defclass so that it
would automatically supply a

(class-proplist :initform nil :initarg :class-proplist :accessor
class-proplist :allocation :class)

form in every class that was defined from some point onwards.

This turned out to be a bad solution since with every new version that
my Lisp vendor supplied, I had to verify that my patched version of
defclass was identical to the new version. And changing defclass was
certainly not standard ... but in my case this was not detrimental.

Along came MOP ... and with optimism I tried to coax the system to
offer me this derivation of CL that I desired. Without much success I
reinstated defclass back to the original CL standard and now use a
global hash table to store class variables, accessed via class
instances. I am dismayed by my failure to implement this elegantly
since the data is now removed from the class object altogether, but it
works.