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

issue EVAL-WHEN-NON-TOP-LEVEL



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 --