Forum: Compiler Issue: 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 DEFTYPE. 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.