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

issue EVAL-WHEN-NON-TOP-LEVEL, version 3



This version incorporates some minor wording changes suggested by JonL.

Issue:		EVAL-WHEN-NON-TOP-LEVEL
References:	CLtL p. 69-70
		Issue DEFINING-MACROS-NON-TOP-LEVEL
Category:	CHANGE, CLARIFICATION
Edit History:   6-May-88, V1 by Sandra Loosemore
		16 Dec 1988, V2 by Sandra Loosemore (alternate direction)
		30 Dec 1988, V3 by Sandra Loosemore (minor wording changes)


Problem Description:

The current description of how the compiler should handle EVAL-WHEN
only makes sense when it appears as a top-level form in the file being
compiled.  Is it legitimate for EVAL-WHEN to appear in non-top-level
locations?  What does it mean in such places?


Proposal EVAL-WHEN-NON-TOP-LEVEL:IGNORE-COMPILE:

Clarify that EVAL-WHEN may appear both at top-level and at
non-top-level.  In non-top-level locations, however, the COMPILE
situation is effectively ignored.

More specifically, when an EVAL-WHEN form is processed by the
interpreter (that is, by the function EVAL), the presence of the EVAL
situation indicates that the body of the EVAL-WHEN should be evaluated
as an implicit PROGN.  Otherwise, EVAL-WHEN returns NIL without
evaluating the body.  The interpreter ignores the COMPILE and LOAD
situations.

When an EVAL-WHEN form is processed by the compiler:

    First, if the situation COMPILE is specified:

        - If the EVAL-WHEN form appears at top level (as defined in
          proposal DEFINING-MACROS-NON-TOP-LEVEL:ALLOW), then each of 
          the forms within the body of the EVAL-WHEN are evaluated by
	  the compiler in the null lexical environment using the 
          function EVAL.

	- Otherwise, no compile-time evaluation takes place.  An
          implementation is permitted to signal a warning to indicate
          that the compile-time evaluation is being ignored.

    Then, if the situation LOAD is specified, then the compiler treats
        the body of the EVAL-WHEN form as if it were an implicit PROGN.
        If the situation LOAD is not specified, then the compiler should
        treat the EVAL-WHEN form as if it were a constant value of NIL.

    The compiler ignores the EVAL situation.


Rationale:

Restricting compile-time evaluation to top-level locations prevents
complications resulting from performing the evaluation in the wrong
lexical environment.

The behavior specified for top-level EVAL-WHENs in this proposal
differs slightly from that described in CLtL.  In the case where both
COMPILE and LOAD are specified, CLtL indicates that the compile-time
evaluation should be interleaved with normal compiler processing of
each of the forms in the body, while this proposal specifies that the
evaluation of all of the body forms should take place before any of
the normal compiler processing (leading to possible multiple
evaluations in the case of nested EVAL-WHENs).  However, it is
unlikely that this would cause serious problems for any user programs.
The nesting behavior of EVAL-WHEN as described in CLtL has been
criticized as overly complicated and hard to understand, while this
proposal is much less complicated.

Allowing implementations to signal a warning when ignoring a
non-top-level EVAL-WHEN allows users to be informed that something
unusual is going on.


Current Practice:

IIM Common Lisp implements this proposal.  Kim Barrett contributed the
following code that illustrates their implementation:

    (defmacro eval-when (situations &body body &environment env)
      (if (not (compiler-environment-p env))
          (when (member 'eval situations) `(progn ,@body))
          (progn
	    (when (member 'compile situations)
	      (if (compiler-at-top-level-p env)
	          (mapc #'eval body)
	          (warn "Top-level form encountered at non-top-level.")))
	    (when (member 'load situations) `(progn ,@body)))))


Cost to implementors:

Probably fairly minor in most implementations.  


Cost to users:

Except for the change relating to possible multiple evaluation of
nested EVAL-WHENs, this proposal is a compatible extension.


Benefits:

The behavior of EVAL-WHEN is easier to understand.  Making EVAL-WHEN
meaningful at non-top-level locations makes it more generally useful,
for example in the expansion of defining macros.


Discussion:

Proposal DEFINING-MACROS-NON-TOP-LEVEL:ALLOW provides a definition for
the term "top-level".
-------