[Openmcl-devel] Bug or spec change?
Ron Garret
ron at flownet.com
Fri Mar 5 11:16:40 PST 2021
I stand corrected.
On Mar 5, 2021, at 10:24 AM, Shannon Spires <svs at bearlanding.com> wrote:
> See comments inline.
> -SS
>
> On 3/5/21 9:25 AM, Ron Garret wrote:
>>
>> 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.
>>
>> Yes.
>>
>>> 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)))
>>> #<STANDARD-CLASS COUNTED-CLASS>
>>> ? (defclass counted-rectangle (rectangle)
>>> ()
>>> (:metaclass counted-class))
>>> #<COUNTED-CLASS COUNTED-RECTANGLE>
>>> ?
>
> You haven't shown the definition of rectangle above. Let's include that:
>
> Clozure Common Lisp Version 1.12-dev (v1.12-dev.5-22-g0430f8db) DarwinX8664
>
> For more information about CCL, please see http://ccl.clozure.com.
>
> CCL is free software. It is distributed under the terms of the Apache
> Licence, Version 2.0.
> ? (defclass counted-class (standard-class)
> ((counter :initform 0)))
> #<STANDARD-CLASS COUNTED-CLASS>
> ? (defclass rectangle ()
> ((height :initform 0.0 :initarg :height)
> (width :initform 0.0 :initarg :width)))
> #<STANDARD-CLASS RECTANGLE>
> ? (defclass counted-rectangle (rectangle)
> ()
> (:metaclass counted-class))
> > Error: The class #<STANDARD-CLASS RECTANGLE> was specified as a
> > super-class of the class #<COUNTED-CLASS COUNTED-RECTANGLE>;
> > but the meta-classes #<STANDARD-CLASS STANDARD-CLASS> and
> > #<STANDARD-CLASS COUNTED-CLASS> are incompatible.
> > While executing: #<CCL::STANDARD-KERNEL-METHOD CCL::ENSURE-CLASS-INITIALIZED (CCL::SLOTS-CLASS)>, in process Listener(4).
> > Type cmd-. to abort, cmd-\ for a list of available restarts.
> > Type :? for other options.
> 1 >
>
> Oops. It doesn't work if rectangle's definition doesn't include (:metaclass counted-class).
>
> But your point is valid because I didn't test for the case of defining rectangle after defining counted-rectangle. That works even when rectangle does not include (:metaclass counted-class). The order of class definitions shouldn't matter; I think that's probably a bug.
>
>> But that is not the same thing as creating “an instance of COUNTED-CLASS which inherits from RECTANGLE”:
>>
>>> ? (class-of (find-class 'counted-rectangle))
>>> #<STANDARD-CLASS COUNTED-CLASS>
>>> ? (class-direct-superclasses *)
>>> (#<STANDARD-CLASS STANDARD-CLASS>)
>>> ?
>>
>> In this case, COUNTED-CLASS inherits only from STANDARD-CLASS, not from RECTANGLE. And that does indeed make sense.
>
> This is where it's important to use precise terminology.
>
> COUNTED-RECTANGLE is literally "The class metaobject named COUNTED-RECTANGLE which happens to be an instance of COUNTED-CLASS, and which also happens to inherit from RECTANGLE." This makes perfect sense when one understands that COUNTED-RECTANGLE is a class metaobject, because only class metaobjects can "inherit" from anything. (Ordinary CLOS objects that are not class metaobjects cannot "inherit" from anything. They are merely instances of a single class, period. Although we might loosely say things like "the LION named Sam inherits from CARNIVORE and SAVANNAH-RESIDENT" that phrasing is not technically accurate; only the class LION can inherit from CARNIVORE and SAVANNAH-RESIDENT. As an instance of LION, Sam has no "inheritance" relationship with anything (except perhaps his ancestor lions, but that's not the kind of "inheritance" we're talking about here.))
>
> The :direct-superclasses argument in the AMOP example specifies the inheritance relationship for class metaobjects. It expresses the same thing as (rectangle) below:
>
> (defclass counted-rectangle (rectangle)
> ()
> (:metaclass counted-class))
>
> Which again makes perfect 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.
>
> It only works if you define RECTANGLE after COUNTED-RECTANGLE. Which I think is probably a bug.
>
>>
>> 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,
>
> Nope. Again, :direct-superclasses is about the superclasses of the class metaobject; it is not about the metaclass of the class metaobject.
>
>
>>> 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)
>> T
>> ? (typep (make-instance 'counted-class) 'class)
>> T
>> ? (typep (make-instance 'rectangle) 'class)
>> NIL
>>
>> 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.
>>
>> rg
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.clozure.com/pipermail/openmcl-devel/attachments/20210305/cca56186/attachment.htm>
More information about the Openmcl-devel
mailing list