[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Moon's comments on Draft 11

Moon's comments on Draft 11 of the CLOS Metaobject Protocol specification,
dated July 30, 1990


Page 1 says that the Standard Protocol section has not been revised and I
shouldn't read it because it will only confuse me.  The problem is that I
can't read the function description pages without knowing what protocols they
are supposed to implement.  As a result, I am only able to comment on pages 5
through 22.  The fact that only this small fraction of the specification has
been written so far makes the schedule pretty implausible in my opinion
(final comments November 15, go to press in January).  As for the content of
pages 5 through 22, on the whole it's pretty good.

3-9 "The declarations are available as a list of declarations" -- I was unsure
whether you meant declarations or decl-specs, that is, a list ((DECLARE foo)
(DECLARE bar)) or a list (foo bar).  I was unable to find anything in the
document that would clarify this, especially since there is no section on the
expansion of the DEFGENERIC macro.  My confusion is augmented by the fact that
88-002R says the syntax of DEFGENERIC involves (DECLARE {declaration}+) yet
other places in 88-002R, e.g. the syntax of DEFMETHOD, use "declaration" the
same as CLtL2 p.215, which says a declaration is a list whose car is DECLARE.
CLOS's terminology is not consistent with CLtL's terminology, and is not even
self-consistent.  Neither KMP nor I think there is a well-defined official
ANSI CL terminology here, however KMP is now leaning towards using "declaration"
to mean what CLtL calls a "decl-spec" and using "DECLARE expression" to
mean what CLtL calls a "declaration".  This seems reasonable to me.  This is
not only a documentation terminology issue; on p.3-93 there is a function
listed called GENERIC-FUNCTION-DECLARATIONS (although this is one of the
unrevised pages that we are not supposed to read); this function also exists
in Symbolics CLOS, although at present it does not have any methods, and
exists in Lucid CLOS where it returns a list of decl-specs.  It would be
unfortunate if there was a function named GENERIC-FUNCTION-DECLARATIONS but it
returned decl-specs rather than declarations.  If this function does what I
suspect it does, and KMP's terminology is adopted, then everything will be
consistent, which would be nice.

3-10 There are a bunch of problems with the table of inheritance structure of
metaobject classes:

  There are no subclasses of funcallable-standard-object; I suspect that
  standard-generic-function should be one.  If it's true, as reported in the
  paragraph after the table, that generic-function is an instance of
  funcallable-standard-class, then generic-function should also be a subclass
  of funcallable-standard-object.  However I question whether, as an abstract
  class, generic-function should be committed to being a

  I question whether standard-accessor-method should inherit from
  standard-method (although it does so in Symbolics CLOS); there is no place
  other than standard-method to attach behavior related to methods that have
  method-functions, yet accessor methods do not have method-functions (at
  least not in the same way that normal methods do), and thus should not be
  inheriting the behavior associated with them.  The problem here is that
  standard-method is being used both as a concrete class (defmethod
  instantiates it) and as an abstract class (standard-accessor-method inherits
  from it); this is almost always a signal of incorrect modularity.  I believe
  standard-accessor-method should be a direct subclass of method.

  My final two comments are of lesser importance:

  There is a sentence fragment in the paragraph after the table that may have
  been intended as a caption.

  In each of the three classes for which multiple direct superclasses are listed,
  the order seems backwards to me because the class that seems more specific to
  me is listed second.  However, Symbolics CLOS agrees with the specification here.

3-11 "interposed" Does this imply that in any CPL that includes C1, the
classes C1, I, and C2 must appear in that order?  I think you intended that,
and it's implied by the standard CPL rules, but since nothing says
non-specified classes can't use different CPL rules, I think this should be
stated explicitly if it's what you intend.

3-13 The last bullet on this page, the one with the implementation note, seems
silly to me.  I see no reason why that information can't be recomputed when
something is redefined.  The restriction should either be removed or
convincingly motivated.

3-17 It seems like a crock for the value of :initform to be unspecified when
:initfunction is missing.  What's the harm in requiring that either both be
present or both be missing?

3-17 As I think I have pointed out before, this scheme for extended slot
options can't work.  Saying that the value is the option if it appears once,
but a list of the options if it appears twice, causes a syntactic ambiguity.
More seriously, it is entirely outside the spirit of Lisp to have one
mechanism for the builtin slot options such as :initform and an entirely
different mechanism for user-defined slot options.  If the extension mechanism
is incapable of implementing the built-in facilities, that's a sure sign of
bad design.  What's wrong with a very simple protocol for expanding slot
options, such as a generic function expand-slot-option of a class (actually
the prototype of the metaclass), the slot-option keyword, the object following
the slot-option keyword, and the canonicalized slot specification so far,
returning an updated canonicalized slot specification?  (The last argument and
the value are each actually a list of forms, which when evaluated and collected
into a list will construct the canonicalized slot specification.)  Only people
who think EQL specializers should be flushed could object to this.  There can
be a very similar expand-class-option function.  Cyphers had a hairier proposal
that allowed the class and slot options to interact, but since that isn't
necessary to implement the built-in options I would leave out the hair.

3-17 How come the :direct-default-initargs keyword argument to ensure-class
doesn't have the same name as the class-option it represents?

3-17 A canonicalized default initarg in Symbolics CLOS is a list of four
elements, where the first three are as the specification says and the fourth
is a summary of the side-effects of the form.  This kind of extensibility should
be allowed.  Personally I think it's a crock that this isn't a property list
like a canonicalized slot specification.

3-19 This is not actually anything explicit in the MOP, but the example of
extended slot options and class options on this page shows what I have long
regarded as a flaw in thinking of how to extend CLOS, namely an excessive
concern with name conflicts as the only problem that might arise when using
different extensions together.  The result of this is that extensions aren't
allowed to use keyword symbols, because there is an idea that putting
everything in its own package will eliminate conflicts.  But this is contrary
to the spirit of Lisp, which says that user-defined extensions shouldn't look
syntactically different from the base language.  Another way of saying the
same thing is that extension designers are not going to be happy being
forbidden to use keywords when the CLOS designers refused to accept the same
restriction themselves.  Name conflicts aren't a big problem anyway compared
to some of the other problems that could occur if you tried to use two CLOS
extensions at the same time anyway.  Lucy Berlin's paper at OOPSLA 90 touches
on this.  I think extensions should be allowed to use whatever symbols they
want, and in fact encouraged to use keyword symbols for naming options, and
that the MOP should not pretend to make it unnecessary for extension writers
to coordinate with each other.  That's really not a CLOS issue anyway, it's
really a programming methodology issue, how do you write programs that are
good citizens of the shared Lisp world, and should be addressed at that level.

3-21, 3-22 "a non-null value for the :environment keyword argument."  This
is no good, there should be specific predicates for environments, not this
violation of abstraction.  If the MOP can't figure out how to deal with the
compile-file environment issue, it shouldn't say anything about it at all,
not say something that will have to be repudiated later.

3-22 "all of the initialization argument values must have applicable methods
for the generic function make-load-form" -- this is inaccurate, since the
specification of make-load-form says it is only called for certain
metaclasses.  What you are really trying to say (and I'm not sure why it's
only said under make-method-lambda and not in all the other places that
generate stuff that gets dumped by compile-file) is that all of the
initialization argument names and values must be objects that are allowed in
compiled constants (CLtL2 p.691).


The Xerox DocuTech Publishing System does not do a very good job of keeping
the pages in order.  However, I did not discover any pages that were actually

3-8: "The name, allocation, and type are available as forms" -- these are of
course objects, not forms.

3-11 stray "bf"

3-12 "from from" appears twice

3-13 "a small number of related" what?  Probably methods.

3-18 How come the last bullet under slot options ("An implementation is free
to add...") isn't repeated for class options?

3-18 I think I understand what the paragraph about ordering of arguments to
ensure-class is trying to say, and I agree that it's reasonable, however it
needs to be rewritten in better English.  Use simpler sentence structure
and a list of prescriptive requirements rather than a general requirement,
an exception, and an exception to the exception, and it will be a lot easier
to follow.

3-19 "effected" -> "affected"

3-21 "generic-function-default-method-class" in the figure is probably
supposed to be "generic-function-method-class".

3-22 In Fig 3-5 "<environment>" is mis-indented.