[Openmcl-devel] Bug or spec change?
Shannon Spires
svs at bearlanding.com
Fri Mar 5 10:24:22 PST 2021
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
> <mailto: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/c10ce9ad/attachment.htm>
More information about the Openmcl-devel
mailing list