From: David E. Young
Subject: Getting shared slot without instance
Date: 
Message-ID: <390EDD46.CF284F76@mindspring.com>
Greetings. I'm wondering if there is a "proper" way in CLOS to retrieve
the value of a shared (i.e. :ALLOCATION :CLASS) slot without having
access to an instance of the class; perhaps something similar to the way
one would access a static member variable in Java or C++. I've had a
cursory look at the MOP and know how to retrieve the slots associated
with a class; perhaps one just shouldn't do this with CLOS? Thanks for
your assistance.

Regards,

-- 

-----------------------------------------------------------------
David E. Young
Fujitsu Network Communications  "The fact that ... we still
(········@computer.org)          live well cannot ease the pain of
                                 feeling that we no longer live nobly."
                                  -- John Updike
"Programming should be fun,
 programs should be beautiful"
  -- P. Graham

From: Robert Monfera
Subject: Re: Getting shared slot without instance
Date: 
Message-ID: <390F6231.7A52A614@fisec.com>
"David E. Young" wrote:

> I'm wondering if there is a "proper" way in CLOS to retrieve
> the value of a shared (i.e. :ALLOCATION :CLASS) slot without having
> access to an instance of the class

I am not aware of a way of doing so.  I thought slot-value-using-class
maybe can do it this way:

(clos:slot-value-using-class (find-class 'standard-class) 
                             (make-instance 'standard-object) 
                             'bar)

- but for example ACL does not seem to care about the class argument:

> (clos:slot-value-using-class (find-class 'standard-class) 
                               (make-instance 'zuk) 
                               'bar)
BAZ

I expected that clos:slot-value-using-class would primarily rely on the
CLASS argument rather than (CLASS-OF OBJECT) for performance reasons,
but probably it is not the case.

Robert
From: Tim Bradshaw
Subject: Re: Getting shared slot without instance
Date: 
Message-ID: <ey3pur4pidw.fsf@cley.com>
* David E Young wrote:
> Greetings. I'm wondering if there is a "proper" way in CLOS to retrieve
> the value of a shared (i.e. :ALLOCATION :CLASS) slot without having
> access to an instance of the class; perhaps something similar to the way
> one would access a static member variable in Java or C++. I've had a
> cursory look at the MOP and know how to retrieve the slots associated
> with a class; perhaps one just shouldn't do this with CLOS? Thanks for
> your assistance.

If you are happy to use a MOP, and if you have a Lisp that is close to
AMOP, then you can probbably use something based around
CLASS-PROTOTYPE, to get a prototype instance.

Some issues that you need to sort out (I don't know the answers to
these, at least not without without reading AMOP!):

	you need to make sure the class is finalized -- I think this
	is a matter of just calling FINALIZE-INHERITANCE on it, but
	I'm not sure.

	It's not clear to me that if a `real' instance of the class
	has never been made whether any of the code that might need to
	run to initialize the class slots will have run, so the slots
	could be uninitialized.

--tim
From: Tim Bradshaw
Subject: Re: Getting shared slot without instance
Date: 
Message-ID: <ey3k8hcovar.fsf@cley.com>
* I wrote:

> If you are happy to use a MOP, and if you have a Lisp that is close to
> AMOP, then you can probbably use something based around
> CLASS-PROTOTYPE, to get a prototype instance.

I meant to attach what I use, but I couldn't find it.  This is
basically it.  I'd like to know if anyone knows whether this will
actually work if no instances have been made (is the prototype
initialised in that case?):


    (in-package :cl-user)
    #+allegro
    (use-package :clos)

    (defgeneric class-slot-value (class slot-name))

    (defmethod class-slot-value ((class standard-class) slot-name)
      (unless (class-finalized-p class)
	(finalize-inheritance class))
      (slot-value (class-prototype class) slot-name))

    (defmethod class-slot-value ((class symbol) slot-name)
      (class-slot-value (find-class class) slot-name))

--tim
From: Francis Leboutte
Subject: Re: Getting shared slot without instance
Date: 
Message-ID: <dt40hs0vf47edo0ffr20rap9bljgju5n57@4ax.com>
Tim Bradshaw <···@cley.com> wrote:

>* I wrote:
>
>> If you are happy to use a MOP, and if you have a Lisp that is close to
>> AMOP, then you can probbably use something based around
>> CLASS-PROTOTYPE, to get a prototype instance.
>
>I meant to attach what I use, but I couldn't find it.  This is
>basically it.  I'd like to know if anyone knows whether this will
>actually work if no instances have been made (is the prototype
>initialised in that case?):
>
>
>    (in-package :cl-user)
>    #+allegro
>    (use-package :clos)
>
>    (defgeneric class-slot-value (class slot-name))
>
>    (defmethod class-slot-value ((class standard-class) slot-name)
>      (unless (class-finalized-p class)
>	(finalize-inheritance class))
>      (slot-value (class-prototype class) slot-name))
>
>    (defmethod class-slot-value ((class symbol) slot-name)
>      (class-slot-value (find-class class) slot-name))
>

I use something similar with ACL (windows). This works fine even if there
is no instances (for persistent classes too - Allegrostore) .

Same thing to set the value of such a slot  :

(defmethod (setf class-slot-value) (new (class symbol) slot-name)
  (setf (class-slot-value (find-class class) slot-name)
    new))

(defmethod (setf class-slot-value) (new (class standard-class) slot-name)
  (unless (class-finalized-p class)
    (finalize-inheritance class))
  (setf (slot-value (class-prototype class) slot-name)
    new))

F.
--
Francis Leboutte
··@algo.be   www.algo.be   +32-(0)4.388.39.19
From: Steven M. Haflich
Subject: Re: Getting shared slot without instance
Date: 
Message-ID: <391B8308.EDDAC1C0@franz.com>
Francis Leboutte wrote:
> I use something similar with ACL (windows). This works fine even if there
> is no instances (for persistent classes too - Allegrostore) .
> 
> Same thing to set the value of such a slot  :
> 
> (defmethod (setf class-slot-value) (new (class symbol) slot-name)
>   (setf (class-slot-value (find-class class) slot-name)
>     new))
> 
> (defmethod (setf class-slot-value) (new (class standard-class) slot-name)
>   (unless (class-finalized-p class)
>     (finalize-inheritance class))
>   (setf (slot-value (class-prototype class) slot-name)
>     new))

Sorry, but this doesn't work in all cases.

The problem is that not all classes are finalizable, yet a class may
still define a class slot.  A class may be logically abstract and may
enforce its abstraction by having a MOP method that checks whether
it is being finalized.  If so, any method that accesses class-slots
via finalization is doomed to failure.

It violates my sense of organization for something like an accessor
to side-effect a class, such as finalizing it.  It would be more
aethetic for me if these methods checked whether the class were
already finalized (in which case the value can reliably be checked
for slot-boundp and then retrieved) and if not, signal error.  A slot
cannot possibly be bound unless the class has been finalized.
From: Francis Leboutte
Subject: Re: Getting shared slot without instance
Date: 
Message-ID: <ea50isgq4hthjhp9le7ekued7cubuq6ace@4ax.com>
"Steven M. Haflich" <····@franz.com> wrote:

>Francis Leboutte wrote:
>> I use something similar with ACL (windows). This works fine even if there
>> is no instances (for persistent classes too - Allegrostore) .
>> 
>> Same thing to set the value of such a slot  :
>> 
>> (defmethod (setf class-slot-value) (new (class symbol) slot-name)
>>   (setf (class-slot-value (find-class class) slot-name)
>>     new))
>> 
>> (defmethod (setf class-slot-value) (new (class standard-class) slot-name)
>>   (unless (class-finalized-p class)
>>     (finalize-inheritance class))
>>   (setf (slot-value (class-prototype class) slot-name)
>>     new))
>
>Sorry, but this doesn't work in all cases.
>
>The problem is that not all classes are finalizable, yet a class may
>still define a class slot.  A class may be logically abstract and may
>enforce its abstraction by having a MOP method that checks whether
>it is being finalized.  If so, any method that accesses class-slots
>via finalization is doomed to failure.
>
>It violates my sense of organization for something like an accessor
>to side-effect a class, such as finalizing it.  It would be more
>aethetic for me if these methods checked whether the class were
>already finalized (in which case the value can reliably be checked
>for slot-boundp and then retrieved) and if not, signal error.  A slot
>cannot possibly be bound unless the class has been finalized.

From a pragmatic point of view, it is not unthinkable to have to access a
class slot of a class with no instance. For example, imagine a slot to
count the number of instances of a class (:initform 0). BTW to be really
useful such a slot should be defined for a class and every subclasses.
Which brings me once more to ask the Lisp makers (and especially Franz) to
give us an 'each-class' slot allocation and something like this
class-slot-value function. Maybe shall I have a pleasant surprise in a few
months, with ACL6 :-)

--
Francis Leboutte
··@algo.be   www.algo.be   +32-(0)4.388.39.19
From: Steven M. Haflich
Subject: Re: Getting shared slot without instance
Date: 
Message-ID: <39206FDF.64FFDFBC@franz.com>
   From: Francis Leboutte <··········@algo.be>

   From a pragmatic point of view, it is not unthinkable to have to access a
   class slot of a class with no instance. For example, imagine a slot to
   count the number of instances of a class (:initform 0).

It _is_ unthinkable in a way: A slot is a property of an instance, and
SLOT-VALUE (really SLOT-VALUE-USING-CLASS, which is the theoretical
underlying mechanism for all the various slot access syntaxes)
requires an instance as its first argument.  I think this is
superficially supposed to make sense, and it does.  Slot-value is an
aproporiate mechanism only when you have an instance.

Slots are elements of instances.  Whether or not a slot happens to be
shared by all instances of a class is part of the implementation of
the class and ought not directly be visible to clients of instances of
that class.  There are other ways slots can be implemented than the
standard way.  For example, an object with a great many
infrequently-used slots might be implemented by a metaclass that keeps
its slots in a hashtable.  That too should not be visible to clients.

But why do you insist on calling this property a slot?  You want this
property to be accessible even when no instances exist.  What you seem
to want is a property of the class, not an instance.  Stated that way,
the answer becomes obvious: Customize the metaclass and give the
metaclass whatever extra slots you want.  It is to me much more direct
to write

     (foo my-class)

than to write

     (foo (class-prototype my-class))

Re your next comment:

   Which brings me once more to ask the Lisp makers (and especially
   Franz) to give us an 'each-class' slot allocation and something
   like this class-slot-value function. Maybe shall I have a pleasant
   surprise in a few months, with ACL6 :-)

I don't agree about class-slot-value, since it isn't clear what the
arguments should be, or why client code should have to know whether a
slot is or is not implemented as a class-slot, or what the behavior
should be if called prior to finalization, or whether to require the
implementation to initialize class slots at finalization time
instead of (the current requirement) no later than the creation of
the first instance.

I do agree with you about and each-class slot allocation, but
directing this indirect request (:-) to me is ineffective as I have
for some years been completely separated from Common Lisp development
at Franz.  You should present your request to sales.

On the other hand, I happen to know that this feature has been present
in ACL ever since I implemented it around 1990.  The necessary
:allocation option value isn't in the keyword package, but any clever
Lisp programmer could certainly discover it with apropos.  See if you
can extract some statement from Franz that it won't change
gratuitously and that it would _probably_ be safe to use it in your
code.

Although I can't speak for Franz, I can speak as the current chair of
NCITS/J13.  [Begin shameless plug] The :each-class feature has been
implemented by more than one vendor, and has been discussed favorably
any number of times.  It is upward compatible, so I consider it as
uncontroversial as any language enhancement is likely to be.  But I
also notice that your organization, a Common Lisp user, is _not_ a
member of the Common Lisp standards committee.  If you want to work
towards improvements like this, you should or your employer should
join J13 and you should present appropriate proposals to the
committee.  The committee does not lack good ideas for things it could
work on.  The committee lacks enough people with sufficient time and
desire to work on things.  I could put you in touch with other members
who have expressed interest in working on CLOS/MOP improvements.  [End
shameless plug]

Once you've done that there are a few open technical issues about
:each-class.  For one in particular, review ANS 7.5.3 Inheritance of
Slots and Slot Options.  A :class slot allocation can be shadowed by
any like-named slot definition in a subclass, but all other slot
options are inherited and merged/collected (:initform :documentation
:reader :writer :accessor :type).  You'll need to define the behavior
of :each-class, and the right behavior isn't immediately obvious to
me.  The :class allocation says that this particular class maintains a
class slot that subclasses might or might not see.  But the
:each-class specification suggests that each�subclass should maintain
it's own slot.  Shadowing the slot violates this assumption.  I'll try
to state it another way: A :class slot allocation says something local
about that particular class that might or might not be seen by its
subclasses, but the :each-class slot allocation tries to say something
pervasively about all subclasses.

I haven't considered this or other inheritance issues carefully and
the issues might not be deep, but they need to be considered.
From: Francis Leboutte
Subject: Re: Getting shared slot without instance
Date: 
Message-ID: <7rs2iskhcmje5dal12hd9emhm783pinqqs@4ax.com>
"Steven M. Haflich" <···@franz.com> wrote:

>   From: Francis Leboutte <··········@algo.be>
>
>   From a pragmatic point of view, it is not unthinkable to have to access a
>   class slot of a class with no instance. For example, imagine a slot to
>   count the number of instances of a class (:initform 0).
>
>It _is_ unthinkable in a way: A slot is a property of an instance, and
>SLOT-VALUE (really SLOT-VALUE-USING-CLASS, which is the theoretical
>underlying mechanism for all the various slot access syntaxes)
>requires an instance as its first argument.  I think this is
>superficially supposed to make sense, and it does.  Slot-value is an
>aproporiate mechanism only when you have an instance.
>
>Slots are elements of instances.  Whether or not a slot happens to be
>shared by all instances of a class is part of the implementation of
>the class and ought not directly be visible to clients of instances of
>that class.  There are other ways slots can be implemented than the
>standard way.  For example, an object with a great many
>infrequently-used slots might be implemented by a metaclass that keeps
>its slots in a hashtable.  That too should not be visible to clients.
>
>But why do you insist on calling this property a slot?  You want this
>property to be accessible even when no instances exist.  What you seem
>to want is a property of the class, not an instance.  Stated that way,
>the answer becomes obvious: Customize the metaclass and give the
>metaclass whatever extra slots you want.  It is to me much more direct
>to write
>
>     (foo my-class)
>
>than to write
>
>     (foo (class-prototype my-class))

You are perfectly right. When I had to implement this instances counter
property (for a class and its subclasses), I remember having hesitated
which way to choose. I don't remember exactly the reasons why I chose to
implement using a class allocated slot. Maybe it has to do with persistence
(how metaclass information is stored in Allegrostore) or more simply
because at that moment it looked to be the easy way (I tend to be a bit
lazy, the reason why I like to use Lisp).

>Re your next comment:
>
>   Which brings me once more to ask the Lisp makers (and especially
>   Franz) to give us an 'each-class' slot allocation and something
>   like this class-slot-value function. Maybe shall I have a pleasant
>   surprise in a few months, with ACL6 :-)
>
>I don't agree about class-slot-value, since it isn't clear what the
>arguments should be, or why client code should have to know whether a
>slot is or is not implemented as a class-slot, or what the behavior
>should be if called prior to finalization, or whether to require the
>implementation to initialize class slots at finalization time
>instead of (the current requirement) no later than the creation of
>the first instance.

It's why I wrote "something like this class-slot-value function", supposed
to be intentionally vague - vague like my English , please take care :-)  
I would like the client code not to have to know whether a slot is a
class-slot and not to bother about finalization.

Maybe is missing the possibility to model this kind of thing at the class
programming level (without having to use the MOP) and different from using
a slot with an class and each-class allocation.

>I do agree with you about and each-class slot allocation, but
>directing this indirect request (:-) to me is ineffective as I have
>for some years been completely separated from Common Lisp development
>at Franz.  You should present your request to sales.
>
>On the other hand, I happen to know that this feature has been present
>in ACL ever since I implemented it around 1990.  The necessary
>:allocation option value isn't in the keyword package, but any clever
>Lisp programmer could certainly discover it with apropos.  See if you
>can extract some statement from Franz that it won't change
>gratuitously and that it would _probably_ be safe to use it in your
>code.

I am surprised. Because I have sent this request several times for a while,
to various people at Franz , including developers. The first time was about
9 years ago when I start to work with ACL on a Sun.
I am afraid clos::each-class (!) allocation 'll not work for a persistent
slot.

>Although I can't speak for Franz, I can speak as the current chair of
>NCITS/J13.  [Begin shameless plug] The :each-class feature has been
>implemented by more than one vendor, and has been discussed favorably
>any number of times.  It is upward compatible, so I consider it as
>uncontroversial as any language enhancement is likely to be.  But I
>also notice that your organization, a Common Lisp user, is _not_ a
>member of the Common Lisp standards committee.  If you want to work
>towards improvements like this, you should or your employer should
>join J13 and you should present appropriate proposals to the
>committee.  The committee does not lack good ideas for things it could
>work on.  The committee lacks enough people with sufficient time and
>desire to work on things.  I could put you in touch with other members
>who have expressed interest in working on CLOS/MOP improvements.  [End
>shameless plug]

No shame, I'll think about.

>Once you've done that there are a few open technical issues about
>:each-class.  For one in particular, review ANS 7.5.3 Inheritance of
>Slots and Slot Options.  A :class slot allocation can be shadowed by
>any like-named slot definition in a subclass, but all other slot
>options are inherited and merged/collected (:initform :documentation
>:reader :writer :accessor :type).  You'll need to define the behavior
>of :each-class, and the right behavior isn't immediately obvious to
>me.  The :class allocation says that this particular class maintains a
>class slot that subclasses might or might not see.  But the
>:each-class specification suggests that each�subclass should maintain
>it's own slot.  Shadowing the slot violates this assumption.  I'll try
>to state it another way: A :class slot allocation says something local
>about that particular class that might or might not be seen by its
>subclasses, but the :each-class slot allocation tries to say something
>pervasively about all subclasses.
>
>I haven't considered this or other inheritance issues carefully and
>the issues might not be deep, but they need to be considered.

Interesting anyway
--
Francis Leboutte
··@algo.be   www.algo.be   +32-(0)4.388.39.19
From: Frode Vatvedt Fjeld
Subject: Re: Getting shared slot without instance
Date: 
Message-ID: <2hbt2ovx80.fsf@dslab7.cs.uit.no>
"David E. Young" <·······@mindspring.com> writes:

> Greetings. I'm wondering if there is a "proper" way in CLOS to
> retrieve the value of a shared (i.e. :ALLOCATION :CLASS) slot
> without having access to an instance of the class;

I asked the same question a while ago, and I found the most "proper"
way was to use a method with the proper specialization (that simply
returns the class-scoped value) rather than a slot.

-- 
Frode Vatvedt Fjeld
From: Thomas A. Russ
Subject: Re: Getting shared slot without instance
Date: 
Message-ID: <ymizoq7shkv.fsf@sevak.isi.edu>
If your lisp has enough MOP support, there is the CLASS-PROTOTYPE
function which returns a prototypical instance of the class.  You could
then do something like:

(shared-slot-accessor (class-prototype (find-class 'class-name)))

Unfortunately, the last time I really looked at using this (1992), it
wasn't very widely available and in some implementations the
class-prototype wouldn't allow access to class slots until after the
class was finalized -- so you either needed to call a function to
finalize the class or else create an instance of the class (hence what's
the point of class-prototype?) to force finalization.  I would expect
that things have gotten better in the last 8 years...

	
-- 
Thomas A. Russ,  USC/Information Sciences Institute          ···@isi.edu