[Openmcl-devel] Bug or spec change?
Paul Krueger
plkrueger at comcast.net
Fri Mar 5 06:17:37 PST 2021
This is essentially what I was trying to do, namely, find a way to create a class-allocated slot in a newly-defined class, by specifying either an inherited class or a metaclass in some fashion. But a class-allocated slot defined in an inherited class is associated with the superclass, not the new class, so that doesn’t work. It wasn’t immediately obvious to me how to use a metaclass to control that either. The solution that I eventually used, (which works fine) was to define an :around method for ensure-class-using-class that checks to see whether the metaclass keyword argument specifies the class I’ve defined and if so makes changes to the argument list before calling the next method. In my case those changes were to specify an additional superclass so that methods that specialize on that superclass would be used for the new class and also to add a class-allocated slot to the new class.
I did also have to create a validate-superclass method that specifies the compatibility between my new metaclass and standard-class. That was the piece I had been missing.
Thanks for all the responses.
> On Mar 5, 2021, at 2:20 AM, Toomas Altosaar <toomas.altosaar at gmail.com> wrote:
>
>
>> One more comment: This is a bad example on the part of AMOP but for a different reason than Ron described. If you really want a counted-class, using a class-allocated slot is a much better approach. That way you don't need all this metaclass nonsense.
>>
>> -SS
>
> That’s the approach I’ve used:
>
> (cs1 :accessor :cs1 :allocation :class)
>
> in the class definition for some class X. But since I want all inheriting classes of X, e.g., Y, to have its own class allocated slot, I have to repeat the class slot definitions in class Y as well, e.g.,
>
> (cs1 :accessor :cs1 :allocation :class)
>
> ad nauseam. Otherwise I’ll be talking to the unique cs1 slot in class X when dealing with Y.
>
> I understand the behavior, I wish there would be a control mechanism that would allow creating unique class slots for inherited classes, e.g., by stating:
>
> (cs1 :accessor :cs1 :allocation :class :shared-class-allocation nil)
>>
>>
>> On 3/4/21 3:31 PM, Ron Garret wrote:
>>> The first thing to do is to see if a different CL implementation gives the same error:
>>>
>>> ➔ sbcl
>>> This is SBCL 1.1.9, an implementation of ANSI Common Lisp.
>>> More information about SBCL is available at <http://www.sbcl.org/ <http://www.sbcl.org/>>.
>>>
>>> SBCL is free software, provided as is, with absolutely no warranty.
>>> It is mostly in the public domain; some portions are provided under
>>> BSD-style licenses. See the CREDITS and COPYING files in the
>>> distribution for more information.
>>> (defclass rectangle ()
>>> ((height :initform 0.0 :initarg :height)
>>> (width :initform 0.0 :initarg :width)))
>>>
>>> #<STANDARD-CLASS RECTANGLE>
>>> (defclass counted-class (standard-class)
>>> ((counter :initform 0)))
>>>
>>> #<STANDARD-CLASS COUNTED-CLASS>
>>> (make-instance 'counted-class
>>> :name 'counted-rectangle
>>> :direct-superclasses (list (find-class 'rectangle))
>>> :direct-slots ())
>>>
>>> debugger invoked on a SIMPLE-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. Define a method for SB-MOP:VALIDATE-SUPERCLASS to avoid this
>>> error.
>>>
>>> So this appears to be a bug in the MOP book. And, if you think about it, the example in the book really doesn’t make sense. COUNTED-CLASS is a metaclass, i.e. all of its instances are classes. But RECTANGLE is not a meta-class, it is a class. All of its instances are rectangles, which are not classes. So it makes no sense to create an instance of COUNTED-CLASS which inherits from RECTANGLE. The instances of such a class would have to be both classes and rectangles, and that’s not possible.
>>>
>>> rg
>>>
>>> On Mar 4, 2021, at 2:07 PM, Paul Krueger <plkrueger at comcast.net <mailto:plkrueger at comcast.net>> wrote:
>>>
>>>> I was trying to do a little MOP hacking and when what I was trying to do got errors I went back to “The Art of the Metaobject Protocol” and ran an example from there to see if it encountered similar errors, which it did (most of this from p. 72 of the book):
>>>>
>>>> I’m running Clozure Common Lisp Version 1.11.6 (v1.11.6) DarwinX8664
>>>>
>>>> ? (defclass rectangle ()
>>>> ((height :initform 0.0 :initarg :height)
>>>> (width :initform 0.0 :initarg :width)))
>>>> #<STANDARD-CLASS RECTANGLE>
>>>> ? (defclass counted-class (standard-class)
>>>> ((counter :initform 0)))
>>>> #<STANDARD-CLASS COUNTED-CLASS>
>>>> ? (setf (find-class 'counted-rectangle)
>>>> (make-instance 'counted-class
>>>> :name 'counted-rectangle
>>>> :direct-superclasses (list (find-class 'rectangle))
>>>> :direct-slots ()))
>>>>> 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)> <ccl::STANDARD-KERNEL-METHODCCL::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 >
>>>> ?
>>>>
>>>> My question is whether this is a problem with CCL’s implementation or a spec change of some sort that invalidates the example from the book. It’s not clear to me how you could ever employ meta-classes without getting this sort of error in CCL, so if this isn’t a bug, what’s the work-around?
>>>>
>>>> Thanks ...
>>>> _______________________________________________
>>>> Openmcl-devel mailing list
>>>> Openmcl-devel at clozure.com <mailto:Openmcl-devel at clozure.com>
>>>> https://lists.clozure.com/mailman/listinfo/openmcl-devel <https://lists.clozure.com/mailman/listinfo/openmcl-devel>
>>>
>>>
>>>
>>> _______________________________________________
>>> Openmcl-devel mailing list
>>> Openmcl-devel at clozure.com <mailto:Openmcl-devel at clozure.com>
>>> https://lists.clozure.com/mailman/listinfo/openmcl-devel <https://lists.clozure.com/mailman/listinfo/openmcl-devel>
>>
>> _______________________________________________
>> Openmcl-devel mailing list
>> Openmcl-devel at clozure.com
>> https://lists.clozure.com/mailman/listinfo/openmcl-devel
> _______________________________________________
> Openmcl-devel mailing list
> Openmcl-devel at clozure.com
> https://lists.clozure.com/mailman/listinfo/openmcl-devel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.clozure.com/pipermail/openmcl-devel/attachments/20210305/41f8f748/attachment.htm>
More information about the Openmcl-devel
mailing list