From: Matthew Realff
Subject: CLOS - Confusion
Date: 
Message-ID: <1992Feb26.234844.3990@athena.mit.edu>
Dear All,

I am new to CLOS and am having the following problem.

I want to have a class and a subclass with the same slots, bar one or two, which
should have the same values for all instances of the class, but these values
should be different for the class and the sub-class.

I tried the following

(defclass c-1 () (s-1 :allocation :class :accessor s-1 :initarg :s-1)
  (:default-initarg :s-1 5))

(defclass c-2 (c-1) 
  (:default-initarg :s-1 4))

However, when I came to create instances of the classes I found the following
behaviour.

(setq i-1 (make-instance 'c-2))

(s-1 i-1)

4

(setq i-2 (make-instance 'c-1))

(s-1 i-2)

5

(s-1 i-1)

5

Which is not what I wanted at all. (I wanted (s-1 i-1) to return 4)

What should I do to create the desired behaviour ?

Thanks for any help,  Matthew.

From: Simon Leinen
Subject: Re: CLOS - Confusion
Date: 
Message-ID: <SIMON.92Feb27112730@liasun5.epfl.ch>
Matthew Realff writes:
 
   I tried the following

   (defclass c-1 () (s-1 :allocation :class :accessor s-1 :initarg :s-1)
     (:default-initarg :s-1 5))

   (defclass c-2 (c-1) 
     (:default-initarg :s-1 4))

I think you are missing two pairs of parentheses here:

(defclass c-1 ()
    ((s-1 :allocation :class :accessor s-1 :initarg :s-1))
  (:default-initarg :s-1 5))

(defclass c-2 (c-1)
    ()
  (:default-initarg :s-1 4))

The inheritance semantics of the :ALLOCATION :CLASS option are
different from what you think -- the slot S-1 will get an allocation
attribute of "class C-1" and this will not change when the slot is
inherited by C-2.  If you want a different class-slot in a subclass,
you have to specify :ALLOCATION :CLASS in the subclass definition:

(defclass c-2 (c-1)
    ((s-1 :allocation :class))
  (:default-initarg :s-1 4))

should work.  The :INITARG and :ACCESSOR options will be inherited and
don't have to be mentioned.
-- 
Simon.
From: Barry Margolin
Subject: Re: CLOS - Confusion
Date: 
Message-ID: <kqpjbhINNij8@early-bird.think.com>
In article <·····················@athena.mit.edu> ········@athena.mit.edu (Matthew Realff) writes:
>I am new to CLOS and am having the following problem.

There's a separate newsgroup for CLOS, comp.lang.clos.  I'm directing
followups there.

>I want to have a class and a subclass with the same slots, bar one or two, which
>should have the same values for all instances of the class, but these values
>should be different for the class and the sub-class.
>
>I tried the following
>
>(defclass c-1 () (s-1 :allocation :class :accessor s-1 :initarg :s-1)
>  (:default-initarg :s-1 5))
>
>(defclass c-2 (c-1) 
>  (:default-initarg :s-1 4))

You need to repeat the slot specification in C-2.  A shared slot is shared
by all instances of the class and its subclasses, except those that shadow
it.  So you have to do:

(defclass c-2 (c-1) (s-1 :allocation :class :initarg :s-1))
  (:default-initarg :s-1 4))

You don't need to repeat the :ACCESSOR option because the inherited
accessor will work.  That's because accessors are required to behave
equivalently to calling (slot-value <instance> <slot-name>), and this will
always find the most specific slot.
-- 
Barry Margolin
System Manager, Thinking Machines Corp.

······@think.com          {uunet,harvard}!think!barmar
From: Douglas S. Rand
Subject: Re: CLOS - Confusion
Date: 
Message-ID: <DSR.92Feb27102911@chickpea.mitre.org>
There are two ways class variables could be implemented in a language.
One way says that the child classes share the class variable of the
parent and the other says that each class implements it.  

SmallTalk,  CLOS and C++ all implement the former.  Your class
variable s-1 is shared.  When you create an instance of Class c-1 the
initarg sets the class variable to 5 and when you create the instance
of Class c-2 it gets set to 4.  Further,  since all instance share
exactly one copy of the instance variable s-1,  you can access it
via any instance and get the same value.

I hope this helps.

--
Douglas S. Rand 
Internet:   <······@mitre.org>
Snail:	    MITRE, Burlington Road, Bedford, MA 
Disclaimer: MITRE might agree with me - then again...
Amateur Radio: KC1KJ
From: Bob Kerns
Subject: Re: CLOS - Confusion
Date: 
Message-ID: <RWK.92Feb28173718@taunton.crl.dec.com>
In article <·················@chickpea.mitre.org> ···@chickpea.mitre.org (Douglas S. Rand) writes:

   Date: 27 Feb 92 16:29:11 GMT
   From: ···@chickpea.mitre.org (Douglas S. Rand)
   There are two ways class variables could be implemented in a language.
   One way says that the child classes share the class variable of the
   parent and the other says that each class implements it.  

   SmallTalk,  CLOS and C++ all implement the former.  Your class
   variable s-1 is shared.  When you create an instance of Class c-1 the
   initarg sets the class variable to 5 and when you create the instance
   of Class c-2 it gets set to 4.  Further,  since all instance share
   exactly one copy of the instance variable s-1,  you can access it
   via any instance and get the same value.

You know, many times I've wished for the other option.
Not as a default, mind you.  Normal modularity considerations
make the existing behaviour better in most cases.

The typical usage the latter is for tables of all instances of a
particular class.

It's also worth noting that I was surprised by the existing
behaviour.  Somehow, it feels more intuitive.  The arguments
for not generating new instance variables with each subclass
are somehow subtle and unobvious.
From: Douglas S. Rand
Subject: Re: CLOS - Confusion
Date: 
Message-ID: <DSR.92Feb28104804@chickpea.mitre.org>
In article <·················@taunton.crl.dec.com> ···@taunton.crl.dec.com (Bob Kerns) writes:

   In article <·················@chickpea.mitre.org> ···@chickpea.mitre.org (Douglas S. Rand) writes:

      Date: 27 Feb 92 16:29:11 GMT
      From: ···@chickpea.mitre.org (Douglas S. Rand)
      There are two ways class variables could be implemented in a language.
      One way says that the child classes share the class variable of the
      parent and the other says that each class implements it.  
      ...

   You know, many times I've wished for the other option.
   Not as a default, mind you.  Normal modularity considerations
   make the existing behaviour better in most cases.

   The typical usage the latter is for tables of all instances of a
   particular class.

Oh.  I've wanted the behavior a bunch of times in both CLOS and C++,
but you can always emulate the latter.  It's a little worse in C++
where you also have to pay attention to what class's class variable.
--
Douglas S. Rand 
Internet:   <······@mitre.org>
Snail:	    MITRE, Burlington Road, Bedford, MA 
Disclaimer: MITRE might agree with me - then again...
Amateur Radio: KC1KJ