From: Pascal Costanza
Subject: default superclass again
Date: 
Message-ID: <cnibk8$qco$1@f1node01.rhrz.uni-bonn.de>
Hi,

Recently, we had a discussion here about how to ensure that a given 
class is always used as the topmost superclass for a given metaclass. 
(Oh, yes, this is about the MOP. ;)

We have found a scheme that adds the superclass to the end of the list 
of direct superclasses, except when one of those direct superclasses is 
already an instance of the given metaclass. This turned out more 
complicated as expected because of the MOP's notion of 
forward-referenced-class: A forward-referenced-class can turn out as an 
instance of the given metaclass, so one would have to remove the wanted 
superclass on class reinitialization.

I have had a very insightful discussion with Bruno Haible about a 
related topic which made me think harder about this whole enforced 
superclass thing. (He is working on MOP support in clisp which, as far 
as I can judge at the moment, is going to be excellent.)

Anyway, I am pretty sure by now that there is a much simpler scheme to 
achieve what one wants: It should be ok to just blindly add the wanted 
superclass to the end of each list of direct superclasses. The standard 
rules for computing the class precedence list ensure that such a class 
will end up top most anyway. Here is some code that illustrates this:

(defclass my-object (standard-object)
   ()
   (:documentation "The enforced superclass."))

(defclass my-class (standard-class)
   ())

(defmethod initialize-instance :around
   ((class my-class) &rest args
    &key direct-superclasses
    &allow-other-keys)
   (declare (dynamic-extent args))
   (apply #'call-next-method
          class
          :direct-superclasses (append direct-superclasses
                                       (list (find-class 'my-object)))
          args))

(defmethod reinitialize-instance :around
   ((class my-class) &rest args
    &key direct-superclasses
    &allow-other-keys)
   (declare (dynamic-extent args))
   (apply #'call-next-method
          class
          :direct-superclasses (append direct-superclasses
                                       (list (find-class 'my-object)))
          args))

Pretty simple, eh? (I still wonder why Andreas Paepcke's code is 
slightly more complicated...)

There is one caveat for LispWorks users: LispWorks adds standard-object 
to an empty list of direct superclasses as part of expansion of the 
defclass macro whereas the MOP specification says that this should 
happen somewhere in re/initialize-instance. The workaround is to remove 
the class metaobject for standard-object like this:

(append (remove (find-class 'standard-object)
                 direct-superclasses)
         (list (find-class 'my-object)))

...and use this as a value for :direct-superclasses instead. This code 
would also work in other MOP implementations, so one doesn't need to 
conditionalize it.



Pascal

-- 
Pascal Costanza               University of Bonn
·········@p-cos.net           Institute of Computer Science III
http://www.pascalcostanza.de  R�merstr. 164, D-53117 Bonn (Germany)

From: Simon Katz
Subject: Re: default superclass again
Date: 
Message-ID: <v0lpp0pbpv4hl1k0d51teoh10so8856ph9@4ax.com>
On Thu, 18 Nov 2004 15:29:21 +0100, Pascal Costanza <········@web.de>
wrote:

>Hi,
>
>Recently, we had a discussion here about how to ensure that a given 
>class is always used as the topmost superclass for a given metaclass. 
>(Oh, yes, this is about the MOP. ;)
>
>We have found a scheme that adds the superclass to the end of the list 
>of direct superclasses, except when one of those direct superclasses is 
>already an instance of the given metaclass. This turned out more 
>complicated as expected because of the MOP's notion of 
>forward-referenced-class: A forward-referenced-class can turn out as an 
>instance of the given metaclass, so one would have to remove the wanted 
>superclass on class reinitialization.
>
>I have had a very insightful discussion with Bruno Haible about a 
>related topic which made me think harder about this whole enforced 
>superclass thing. (He is working on MOP support in clisp which, as far 
>as I can judge at the moment, is going to be excellent.)
>
>Anyway, I am pretty sure by now that there is a much simpler scheme to 
>achieve what one wants: It should be ok to just blindly add the wanted 
>superclass to the end of each list of direct superclasses. The standard 
>rules for computing the class precedence list ensure that such a class 
>will end up top most anyway. 

[snip]

Yes, I think this will work. (I may even have tried it in the distant
past and run into the difficulties that you mentioned with LispWorks.)

A disadvantage is that displaying inheritance hierarchies as graphs
will be messy because you (probably) get one line for each direct
subclass/superclass link. That's true for the class browser in
LispWorks, at least.

Simon

___________________
Real email address:
(substitute ··@ #\+ (substitute #\s #\! "u!enet001+nomi!tech.com"))
From: Simon Katz
Subject: Re: default superclass again
Date: 
Message-ID: <12mpp0pe8t4b29lf5bd8n5egqed68pla0k@4ax.com>
I wrote:

>A disadvantage is that displaying inheritance hierarchies as graphs
>will be messy because you (probably) get one line for each direct
>subclass/superclass link. That's true for the class browser in
>LispWorks, at least.

FWIW, I think LispWorks does The Right Thing -- I wasn't trying to
suggest that the inheritance browser should try to be "clever" and not
display all subclass/superclass links.

___________________
Real email address:
(substitute ··@ #\+ (substitute #\s #\! "u!enet001+nomi!tech.com"))