Forum: CompilerIssue: CLOS-MACRO-COMPILATION
References: CLOS chapters 1 & 2 (88-002R)
CLOS chapter 3 (89-003)
Issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS
Issue DEFINING-MACROS-NON-TOP-LEVEL
Category: CLARIFICATION
Edit History: V1, 10 Mar 1989, Sandra Loosemore
V2, 13 Mar 1989, Sandra Loosemore
V3, 21 Mar 1989, Sandra Loosemore (fix error language)
V4, 11 Jun 1989, Sandra Loosemore (Gregor's amendment)
V5, 23 Jun 1989, Sandra Loosemore (wording changes per Pitman)
Status: Proposal MINIMAL passed, June 89
Recommendation to drafting committee: clarify that the
provisions listed under DEFCLASS are intended to affect
warnings emitted by the compiler.
Problem Description:
Do the CLOS defining macros (DEFCLASS, DEFMETHOD, DEFGENERIC, and
DEFINE-METHOD-COMBINATION) have compile-time side-effects similar
to those for DEFSTRUCT or DEFMACRO?
A part of the problem is that we do not currently have a full
understanding of all the issues involved. In particular, work on
defining the CLOS meta-object protocol is still in progress. The goal
of this proposal is to say enough about the behavior of these macros
in the standard so that users can use them portably in compiled code,
but to leave as much of the behavior as possible unspecified to avoid
placing undue restrictions on the meta-object protocol.
Proposal CLOS-MACRO-COMPILATION:MINIMAL:
State that top-level calls to the CLOS defining macros have the
following compile-time side-effects. Any other compile-time behavior
is explicitly left unspecified.
DEFCLASS:
* The class name may appear in subsequent type declarations.
* The class name can be used as a specializer in subsequent
DEFMETHOD forms.
DEFGENERIC:
* The generic function can be referenced in subsequent DEFMETHOD forms.
* DEFGENERIC does not arrange for the generic function to be callable
at compile time.
DEFMETHOD:
* DEFMETHOD does not arrange for the method to be callable at compile
time. If there is a generic function with the same name defined at
compile time, compiling a DEFMETHOD does not add the method to that
generic function. (That is, the method is added to the generic
function only when the DEFMETHOD is actually executed.)
The error-signalling behavior described in the specification of
DEFMETHOD in CLOS chapter 2 (if the function isn't a generic function
or if the lambda-list is not congruent) happens only when the defining
form is executed, not at compile time.
The forms in EQL specializers are evaluated when the defining form
is executed. The compiler is permitted to build in knowledge
about what the form in an EQL specializer will evaluate to in cases
where the ultimate result can be syntactically inferred without
actually evaluating it.
DEFINE-METHOD-COMBINATION:
* The method combination can be used in subsequent DEFGENERIC forms.
The body of a DEFINE-METHOD-COMBINATION form is evaluated no earlier
than when the defining macro is executed and possibly as late as
generic function invocation time. The compiler may attempt to
evaluate these forms at compile time but must not depend on being able
to do so.
Rationale:
The compile-time behavior of DEFCLASS is similar to DEFSTRUCT or
DEFGENERIC and DEFMETHOD are similar to DEFUN, which doesn't add the
function definition to the compile-time environment. Since generic
functions may be freely redefined between compile and run time (just
like any other function), a method may end up "belonging" to a
different generic function at load time than at compile time. This
is why it is inappropriate to signal errors about congruency problems
(etc) until the method is actually added to the generic function at
run time.
Current Practice:
The items listed under DEFCLASS in proposal MINIMAL are fairly standard
programming style.
Flavors does not support compile-time instantiation of classes. It
does not make method combinations available at compile-time either, but
Moon considers that to be a bad design choice.
Cost to implementors:
Unknown.
Cost to users:
Unknown, but probably fairly small.
Wrapping an (EVAL-WHEN (EVAL COMPILE LOAD) ...) around the appropriate
definitions will make sure they are fully defined at compile-time.
Alternatively, the definitions could be placed in a separate file,
which is loaded before compiling the file that depends on those
definitions.
Benefits:
Programmers can rely on programs that use the CLOS defining macros
being able to compile correctly in all implementations, without having
to wrap explicit EVAL-WHENs around every macro call.
Discussion:
This writeup is based on discussions between Moon, Gray, and
Loosemore, who are mostly in agreement on the things presented in
proposal MINIMAL. We have purposely avoided saying anything about
whether meta-objects representing the classes, methods, etc. get
created at compile-time, or whether such meta-objects are fully or
partially defined. The basic questions addressed by this issue are
what kinds of things can be defined and then used during compilation
of the same file that defines them, and what restrictions might apply.
These proposals are not completely compatible with the meta-object
protocol document (89-003). Gregor Kiczales says:
No one believes that what is written in draft 10 of the MOP is valid.
Sandra Loosemore says:
Although I admit I don't understand all of the issues involved with
the meta-object protocol, I prefer proposal MINIMAL over
NOT-SO-MINIMAL. I don't think leaving the issue of whether or not
classes can be instantiated at compile-time unspecified places an
undue burden on users, and it does leave more freedom for the
meta-object protocol to decide what the right behavior really is.
Dick Gabriel notes:
The question I have about the process going on with respect to the
CLOS-MACRO-COMPILATION issue is whether the fine-grained behavior of
CLOS under various compilation/evaluation situations is being
over-specified.
At this stage of the game I worry that we might go a little too far in
one direction in specification when we are actually engaged in design
work. This isn't intended to be a criticism of any committees, but I
would feel a lot more comfortable with a conservative specification
that defined well-formed programs being loaded or compiled in fresh
Common Lisps with a pretty simple eval-when model that is easier to
specify and which makes it easy for all but the hairiest
compilation-environment-frobbing programs to be written.