[Openmcl-devel] Bug or spec change?

Ron Garret ron at flownet.com
Fri Mar 5 08:25:40 PST 2021

On Mar 4, 2021, at 10:50 PM, Shannon Spires <svs at bearlanding.com> wrote:

> > So it makes no sense to create an instance of COUNTED-CLASS which inherits from RECTANGLE.
> Sure it does.

No, it doesn’t :-)

> Any given class metaobject has two kinds of relationships with other class metaobjects: It has an INSTANCE-OF relationship with its metaclass and an ISA (or INHERITANCE) relationship with its superclasses.


> The equivalent (and more conventional) definition of counted-rectangle would be
> (defclass counted-rectangle (rectangle)
>   ()
>   (:metaclass counted-class))
> and this makes perfect sense.

Yes.  And it works:

> Welcome to Clozure Common Lisp Version 1.11-r16812M  (DarwinX8664)!
> ? (defclass counted-class (standard-class)
>    ((counter :initform 0)))
> ? (defclass counted-rectangle (rectangle)
>   ()
>   (:metaclass counted-class))
> ? 

But that is not the same thing as creating “an instance of COUNTED-CLASS which inherits from RECTANGLE”:

> ? (class-of (find-class 'counted-rectangle))
> ? (class-direct-superclasses *)
> ? 

In this case, COUNTED-CLASS inherits only from STANDARD-CLASS, not from RECTANGLE.  And that does indeed make sense.

> What doesn't work in the example is that rectangle and counted-rectangle have different metaclasses.

No, that’s not the problem.  In the example as you’ve given it (not as the MOP book gives it), COUNTED-RECTANGLE has a metaclass of COUNTED-CLASS, and RECTANGLE (assuming you define it as the MOP book does) has a meta-class of STANDARD-CLASS.  And all that works just fine.

The problem with the MOP example:

> ? (setf (find-class 'counted-rectangle)
>        (make-instance 'counted-class
>          :name 'counted-rectangle
>          :direct-superclasses (list (find-class 'rectangle))
>          :direct-slots ()))

Is that it is trying to make the metaclass of COUNTED-CLASS be RECTANGLE, and that doesn’t work because RECTANGLE is not a metaclass, it is an *instance* of STANDARD-CLASS.  STANDARD-CLASS can be a metaclass, but an *instance* of STANDARD-CLASS (with the RECTANGLE class is) cannot be.

> Any time class A inherits from class B, they both should be instances of the same metaclass.

That is correct, but you’ve misapplied the rule.  The problem is not that "rectangle and counted-rectangle have different metaclasses”.  The problem in this case is that RECTANGLE and *COUNTED-CLASS* (not counted-rectangle) have different metaclasses.  Having rectangle and counted-rectangle have different metaclasses works perfectly well, as the example above demonstrates.

Another way to illustrate what the problem actually is here:

? (typep (make-instance 'standard-class) 'class)
? (typep (make-instance 'counted-class) 'class)
? (typep (make-instance 'rectangle) 'class)

That is the reason that it makes no sense for RECTANGLE to be a DIRECT-SUPERCLASS of an instance of COUNTED-CLASS.  An instance of COUNTED-CLASS is a class, but an instance of RECTANGLE is not.  So an instance of the resulting chimera would have to be both a class and not a class.

But yeah, it gets pretty confusing.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.clozure.com/pipermail/openmcl-devel/attachments/20210305/9bfac272/attachment.htm>

More information about the Openmcl-devel mailing list