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

Re: Issue: EVAL-WHEN-NON-TOP-LEVEL (Version 5)



    Date: Sun, 12 Feb 89 17:11:16 MST
    From: sandra%defun@cs.utah.edu (Sandra J Loosemore)

    you still haven't said anything to justify the behavior of your proposal
    under example *I* cited in my previous message, namely, why

	(eval-when (load)
	    (defmacro foo ...))

    should cause FOO to be defined in the compile-time environment even when
    the user explicitly specified that the macro only needs to be defined at
    load time.

Among other things, because it is incompatible with CLtL. p70 says:

 If the situation LOAD is specified
 then if the situation COMPILE is also specified
      then ...
      else process each of the forms in the body in not-compile-time mode.

`not-compile-time' mode must see DEFMACRO because the previous page says that
all top-level forms are defaultly processed in not-compile-time mode, which
means that DEFMACRO is normally noticed by the compiler when in that mode.

By the way, even before this issue came up, I would have told you that if you
really wanted macros that were visible only at load time and not at
compile time, the thing would be to put them in a separate file and load
then when you really needed them. Independently of any discussion of
EVAL-WHEN, I believe that to be the right answer to this problem.

Getting back to EVAL-WHEN, though, our semantics allow you to keep something
 from being `noticed' by the compiler by just putting it in a non-top-level
position. 
    (LET () (DEFMACRO FOO ...))
is the easiest way to do that right now, but you can also write: 
 (DEFUN INIT () 
   (DEFMACRO ...)
   (DEFMACRO ...) ...)
 (INIT)

Also, as a matter of pragmatics, I find that it is -extremely- rare to
want DEFMACRO to not be seen at compile time but rather only to be seen at
load time. If it had been desirable, it would have been easy to design a
form like DEFMACRO that did what you suggest. You can define one yourself
by writing something like:
    (defmacro load-time-defmacro (name bvl &body forms)
      `(progn (setf (macro-function ',name) #'(lambda (form env) ...))
	      ',name))
 or (defmacro load-time-defmacro (name bvl &body forms)
      `(let () (defmacro ,name ,bvl ,@forms)))    

    ... Basically, the problem with the nesting behavior specified
    by your proposal and by CLtL is that it provide for any way for the
    programmer

"does not" ? -------------------â??

    "turn off" the compile-time behavior of any of the various defining
    macros like DEFMACRO, or of nested EVAL-WHENs.

I don't agree that this is something that is ever a remarkably interesting
thing to want. Can you sketch a concrete example that demonstrates it as
something that is both useful and not trivially solvable by any of the above
mechanisms?

Finally, while I'm thinking about it, let me retroactively add another design
goal for EVAL-WHEN which I had when I was working on it but never ended up
verbalizing:

 COMPILE must be meaningful in EVAL-WHEN if and only if LOAD is meaningful.
 [If this is not so, it becomes impossible to reliably split a task in half,
  with half the work being done by an (EVAL-WHEN (COMPILE) ...) and the
  other half being done by (EVAL-WHEN (LOAD) ...).]