[CM] OSX - OpenMCL .14, build from CVS w/ CLM

Robert Sayre mint@franklinmint.fm
Sun, 30 Nov 2003 00:58:49 -0500


I've gotten CM to build (and work!) on OpenMCL .14... but I did it
incorrectly. Below, there is a response to my questions about OpenMCL's MOP
from Gary Byers. I made a similar mistake (which Byers corrects) in
FINALIZE-CLASS when I built CM.

>From the last email I sent about this issue:

? (load "/Users/myuser/music/cm/src/cm.lisp")
; Loading "/Users/myuser/music/cm/bin/pkg.dfsl".
; Loading "/Users/myuser/music/cm/bin/openmcl.dfsl".

...

; Compiling "/Users/myuser/music/cm/src/sco.lisp".
; Loading "/Users/myuser/music/cm/bin/sco.dfsl".
> Error in process listener(1):
>   The class #<STANDARD-CLASS EVENT-STREAM> was specified as: a
>   super-class of the class #<IO-CLASS SCO-STREAM>;
>   but the meta-classes #<STANDARD-CLASS STANDARD-CLASS> and
>   #<STANDARD-CLASS IO-CLASS> are incompatible.
> While executing: #<CCL::STANDARD-KERNEL-METHOD SHARED-INITIALIZE :AFTER
(CCL::STD-CLASS T)>

The reply I got from GB indicates that it will be difficult to take care of
the problem by specializing the FINALIZE-CLASS function for OpenMCL. Would
it be possible to declare VALIDATE-SUPERCLASSES methods inline, or would
that break other implementations?

Robert Sayre


------ Forwarded Message
From: Gary Byers <gb@clozure.com>
Date: Sat, 29 Nov 2003 21:57:13 -0700 (MST)
To: Robert Sayre <mint@franklinmint.fm>
Cc: openmcl-devel@clozure.com
Subject: Re: [Openmcl-devel] MOP question


On Sat, 29 Nov 2003, Robert Sayre wrote:

> I have some questions about the MOP in OpenMCL .14 and also about a compiler
> warning. The following example is taken from an old comp.lang.lisp thread
> titled "MOP/pcl anomaly in CMUCL?"*
>
>
> Welcome to OpenMCL Version (Alpha: Darwin) 0.14-031108!
> ? (defclass dynamic-slots-class (standard-class) ())
> #<STANDARD-CLASS DYNAMIC-SLOTS-CLASS>
> ?  (defclass test () ((a1)) (:metaclass dynamic-slots-class))
> > Error in process listener(1): The class #<STANDARD-CLASS STANDARD-OBJECT>
was
> > specified as a
> > super-class of the class #<DYNAMIC-SLOTS-CLASS TEST>;
> > but the meta-classes #<STANDARD-CLASS STANDARD-CLASS> and
> > #<STANDARD-CLASS DYNAMIC-SLOTS-CLASS> are incompatible.
> > While executing: #<CCL::STANDARD-KERNEL-METHOD SHARED-INITIALIZE :AFTER
> (CCL::SLOTS-CLASS T)>
> > Type :POP to abort.
>
>
> From the usenet thread, I learned that
>
> "It's neccessary to define methods on pcl:validate-superclass more often
> than is mentioned in AMOP.
>
> [This] issue will probably lie at the heart of your problem:  Since
> test (whose metaclass is dynamic-slots-class) inherits from t (whose
> metaclass is standard-class), you have to define this combination
> valid"
>

I guess that I could agree that since (a) the default method for
VALIDATE-SUPERCLASS only returns T for a few classes that it knows
about and conservatively returns NIL for those clasees that it doesn't
know about and (b) it's often then case that certain subclass
relationships could exist between a user-defined metaclass and some
other class, it's often necessary to explicitly define specialized
VALIDATE-SUPERCLASS methods.


> So, I followed this advice and it worked:
>
>
> ? (defmethod openmcl-mop:validate-superclass
>     ((class dynamic-slots-class) (super ccl::standard-class))
>   t)
> #<STANDARD-METHOD VALIDATE-SUPERCLASS (DYNAMIC-SLOTS-CLASS STANDARD-CLASS)>
> ? (defclass test () ((a1)) (:metaclass dynamic-slots-class))
> #<DYNAMIC-SLOTS-CLASS TEST>
>
>
> This problem arose while trying to build Common Music for OpenMCL .14.
> Common Music runs on a number of implementations, including OpenMCL .13.7
> and MCL. It appears that neither of them require the combination to be
> declared valid. Is this divergence intentional?

The MOP spec is online at <http://www.lisp.org/mop/index.html>.  I
think that the rationale for requiring that VALIDATE-SUPERCLASS be
called when it is that the question of whether a superclass
relationship can meaningfully exist between two class objects is best
determined by the implementor of those classes, and the implementor
is therefore requuired to define VALIDATE-SUPERCLASS methods to decide
that question.

Neither MCL nor OpenMCL 0.13 make much of an attempt to adhere to the
MOP and OpenMCL 0.14 does, so in that sense the divergence is
intentional.


>
> Also, CM uses a function called "finalize-class" that varies based on
> implementation. I assume it's there for just this sort of situation. When I
> define it the following way, I get a compiler warning, but it seems to work.
> If I uncomment the print statement, there is no warning. In the following
> example, why doesn't the use of "the-class" in defmethod count as a use of
> the variable?
>
> ? (defun finalize-class (the-class)
>   (progn
>     ;(print the-class)
>     (defmethod openmcl-mop:validate-superclass
>         ((the-class class) (super ccl::standard-class))
>             t)))
> ;Compiler warnings :
> ;   Unused lexical variable THE-CLASS, in FINALIZE-CLASS.
> FINALIZE-CLASS
> ? (defclass dynamic-slots-class (standard-class) ())
> #<STANDARD-CLASS DYNAMIC-SLOTS-CLASS>
> ? (finalize-class 'dynamic-slots-class)
> #<STANDARD-METHOD VALIDATE-SUPERCLASS (CLASS STANDARD-CLASS)>
> ? (defclass test () ((a1)) (:metaclass dynamic-slots-class))
> #<DYNAMIC-SLOTS-CLASS TEST>
>

You've (incidentally) defined a method that says that all objects of
class CLASS can have an object of class STANDARD-CLASS as a
superclass; after defining that method, your test case should work,
but probably not for the reason you'd intended (the first specializer
form in your DEFMETHOD seems to have its subforms backwards.)

If you flipped them around, you'd probably get a complaint that
there's no class named THE-CLASS: DEFMETHOD's a macro and it doesn't
evaluate class names used in its argument subforms.  (The fact that
one of those unevaluated class names happens to match an otherwise
unused variable name in the surrounding function's just a
coincidence.)

It's not clear to me that you really want or need to define
a VALIDATE-SUPERCLASSES method procedurally.  (It's also clear that
it's awkward and complicated to do so: macroexpand a DEFMETHOD form,
and ask yourself how often you really want or need to do this ...)
Admittedly, there may be cases where it's necessary to define methods
procedurally and it should be at leest a little esaier than it is to
do so.

In this case, it seems a lot easier to just define the method(s)
"declaratively":

(defclass dynamic-slots-class () ...)

(defmethod openmcl-mop:validate-superclass ((class dynamic-slots-class)
                                            (super standard-class))
  t)


------ End of Forwarded Message