From: Martin A. <ma...@at...> - 2001-09-03 21:47:00
|
William Harold Newman wrote: > > On Mon, Sep 03, 2001 at 02:03:48PM +0200, Martin Atzmueller wrote: > > Why the EVAL ... > > This is, because DEFCLASS might be used in a non-toplevel position > > to define a STRUCTURE-CLASS: > > And there even an (EVAL-WHEN (:COMPILE-TOPLEVEL :LOAD-TOPLEVEL :EXECUTE) > > ...) > > would only be done at execution time, not at compile-time. > > And so the DEFSTRUCT would not be compiled, e.g. since the > > DEFSTRUCT-FORM is built by DEFCLASS, this cannot be inserted at > > macroexpansion time. > > I think we may have a fundamental disagreement here. If I compile > (let ((serial-number-counter 0)) > (defstruct foo > name > rank > (serial-number (incf serial-number-counter)))) > (more-code) > (more-code) > (if (typep *thing* 'foo) > (something) > (something-else)) > then I think it's OK for the compiler to complain about > (TYPEP *THING* 'FOO) referencing an undefined type. > It sounds to me, from what you have written above, as though you > disagree. Sorry if I wasn't clear on that. I completely agree with you. In CLHS, in the description of DEFCLASS, it also says that a type predicate is only established at compile-time, if the defclass happens at top-level. And the point that I really cared about was removing the bogus redefinition warnings in the interpreter (the call to INFORM-TYPE-SYSTEM-ABOUT-STD-CLASS), which only needs the modified EVAL-WHEN situation. And this is completely unrelated to the EVAL for the DEFSTRUCT-P path. What I tried to explain was that I think that the defstruct-form cannot be made to compiled code by COMPILE-FILE, if it is not EVALED before. (The defstruct is stored in a slot of the CLASS being built. In the current implementation this is only available if the class has really been defined before.) Therefore, the corresponding structure to the class would only be defined at load-time, and this might mean a negative performance impact. And it wasn't clear to me, if that was right. If it really happens it is certainly not desirable. > > So, EVAL is needed a macroexpansion time, if we want the DEFSTRUCT > > for the STRUCTURE-CLASS to be compiled. > > I don't see right now, how that exact behavior could be implemented > > using EVAL-WHEN, unfortunately. > > I think the behavior that you want may be non-ANSI-compliant. See the Well, to be more explicit: This is not behavior _I_ want, but behavior that is there right now. I rather described how the old behavior could or could not be preserved. And since I think it can't be fully preserved, it might mean more drastic changes to really fix it, if there is code in SBCL that relies on it. > spec section "3.2.3.1.1 Processing of Defining Macros", in particular > the text above "Figure 3-8. Defining Macros That Affect the > Compile-Time Environment" (including DEFCLASS and DEFSTRUCT): > The next figure lists macros that make definitions available both in > the compilation and run-time environments. It is not specified whether > definitions made available in the compilation environment are > available in the evaluation environment, nor is it specified whether > they are available in subsequent compilation units or subsequent > invocations of the compiler. As with eval-when, these compile-time > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > side effects happen only when the defining macros appear at top level. > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > > See also the definition of DEFCLASS, which says > If a defclass form appears as a top level form, the compiler must make > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > the class name be recognized as a valid type name in subsequent > declarations (as for deftype) and be recognized as a valid class name > for defmethod parameter specializers and for use as the :metaclass > option of a subsequent defclass. > > I don't think the ANSI behavior is ideal in all ways, but it has > two nontrivial advantages: > * It's consistent with EVAL-WHEN, and thus doesn't really add any > complexity beyond EVAL-WHEN. > * You don't need to solve the halting problem in order to comply > with it. > And I don't think it's broken enough that we should do things > differently. (It's less fun to do things differently when you don't > have a lot of high-paying customers to try to lock in.:-) Yes, true. :-) I only wondered if that is consistent with the way SBCL uses its "legacy" maybe-non-ANSI DEFCLASS. All the above is fine with me, since the type predicates are not established by use of the "EVAL code", so maybe all this could be rewritten like I outlined in the previous mail. Something like: (if defstruct-p `(progn (eval-when (:compile-toplevel :execute :load-toplevel) ,defclass-form) (eval-when (:compile-toplevel :execute :load-toplevel) (class-defstruct-form (find-class ',name)))) -- Martin Atzmueller <ma...@at...> |