[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
issue EVAL-WHEN-NON-TOP-LEVEL
- To: sandra@cs.utah.edu
 
- Subject: issue EVAL-WHEN-NON-TOP-LEVEL
 
- From: Jon L White <edsel!jonl@labrea.stanford.edu>
 
- Date: Wed, 18 May 88 02:02:52 PDT
 
- Cc: cl-compiler@sail.stanford.edu
 
- In-reply-to: Sandra J Loosemore's message of Mon, 9 May 88 09:55:33 MDT <8805091555.AA22855@cs.utah.edu>
 
The early part of the Proposal: section probably ought to outline our
intent in giving ordinary macro semantics to EVAL-WHEN -- it is so that 
an piece of source code will either be "processed" as if the body of the 
eval-when is there, or as if it were not there, depending on the dynamic 
state of the processor:
    Original Source    |    Situation Applies   |  Situation Doesn't Apply
-----------------------+------------------------+----------------------------
                       |                        |
  (defun foo (x)       |     (defun foo (x)     |     (defun foo (x)     
    (step1 x)          |       (step1 x)        |       (step1 x)
    (eval-when (...)   |       (step2 x)        |       nil
      (step2 x))       |       (step2 x))       |       (step3 x))
    (step3 x))         |                        |
On can infer this from a careful reading of the proposal, but the 
overwhelming simplicity of making eval-when a small macro is lost "in the 
woods".  This top-level view of the proposal ought to be said very early 
in the proposal, rather than starting out with a myriad of details about 
how the various situations are treated.
I note also that you implicitly assume a dynamic variable *compiling-p*?
This will have to be spelled out in detail, much as in my note of
25 Mar 88 23:21:23 PST "Eval-When -- a radical view";  simply being
"in the compiler" isn't enough since EVAL may have to bind this variable
to nil (or do the equivalent -- Rob points out that we don't really
want to tie down the implementation to an actual dynamic variable, but
rather to the semantics give by the example code).
I very much like the idea of shadowing eval-when with a macrolet in the
situation where there might be nested eval-when's and the outter one has 
at least a 'compile' situation.  In fact, the trial code I sent out in
the msg "Eval-When -- a radical view" doesn't work right;  the attempt
to identify this circumstance with a dynamic binding of a state variable 
(to :eval-before-compile) is wrong, since it really is a lexical effect 
that is needed, not a dynamic one.
Finally, I had a bit of trouble following all the logic in all the 
cond clauses of the sample defmacro for EVAL-WHEN.   Could I offer a 
rewrite, with effusive commentary, that breaks it down into basically
two cases: the "hard" case (presented first) and the "easy" one.
    (defmacro eval-when (situations &body body)
      (cond ((and *compiling-p*
		  (member 'compile situations))
	      ;; Situation Applies: The hard case.  Compiling, and evaluation
	      ;;  is required at compile time too.
	     (eval `(progn ,@body))
	     (if (member 'load situations)
		  ;; Allow normal processing by 'compile-form-to-file',
		  ;;  except ignore sub requests for compile-time evaluation.
		  `(macrolet ((eval-when (situations &body body)
			       (if (member 'load situations)
				   `(PROGN ,@body)
				   'NIL)))
		    ,@body)
		  ;; or skip processing by 'compile-form-to-file'
		  `NIL))
	    ((if *compiling-p*
		 (member 'load situations)
		 (member 'eval situations))
	      ;; Situation Applies: The easy case.  Just return the body code 
	      ;;  for normal processing by 'eval' or 'compile-form-to-file'.
	     `(PROGN ,@body))
	    (t 
	      ;; Hmmm, 'situation' just doesn't apply!
	     `NIL)))
-- JonL --