1
0
Fork 0
cl-sites/HyperSpec-7-0/HyperSpec/Issues/iss147_w.htm
2024-04-01 10:24:07 +02:00

522 lines
40 KiB
HTML

<!-- Common Lisp HyperSpec (TM), version 7.0 generated by Kent M. Pitman on Mon, 11-Apr-2005 2:31am EDT -->
<HTML>
<HEAD>
<TITLE>CLHS: Issue EVAL-WHEN-NON-TOP-LEVEL Writeup</TITLE>
<LINK HREF="../Data/clhs.css" REL="stylesheet" TYPE="text/css" />
<META HTTP-EQUIV="Author" CONTENT="Kent M. Pitman">
<META HTTP-EQUIV="Organization" CONTENT="LispWorks Ltd.">
<LINK REL=TOP HREF="../Front/index.htm">
<LINK REL=COPYRIGHT HREF="../Front/Help.htm#Legal">
<LINK REL=DISCLAIMER HREF="../Front/Help.htm#Disclaimer">
<LINK REL=PREV HREF="../Issues/iss146_w.htm">
<LINK REL=UP HREF="../Issues/iss147.htm">
<LINK REL=NEXT HREF="../Issues/iss148_w.htm">
</HEAD>
<BODY>
<H1><A REV=MADE HREF="http://www.lispworks.com/"><IMG WIDTH=80 HEIGHT=65 ALT="[LISPWORKS]" SRC="../Graphics/LWSmall.gif" ALIGN=Bottom></A><A REL=TOP HREF="../Front/index.htm"><IMG WIDTH=237 HEIGHT=65 ALT="[Common Lisp HyperSpec (TM)]" SRC="../Graphics/CLHS_Sm.gif" ALIGN=Bottom></A> <A REL=PREV HREF="../Issues/iss146_w.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Previous]" SRC="../Graphics/Prev.gif" ALIGN=Bottom></A><A REL=UP HREF="../Issues/iss147.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Up]" SRC="../Graphics/Up.gif" ALIGN=Bottom></A><A REL=NEXT HREF="../Issues/iss148_w.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Next]" SRC="../Graphics/Next.gif" ALIGN=Bottom></A></H1>
<HR>
<H2>Issue EVAL-WHEN-NON-TOP-LEVEL Writeup</H2>
<PRE><B>Issue:</B> <A HREF="iss147.htm">EVAL-WHEN-NON-TOP-LEVEL</A><P>
<B>Forum:</B> Compiler<P>
<B>References:</B> <A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> (CLtL pp69-70),<P>
Issue <A HREF="iss104.htm">DEFINING-MACROS-NON-TOP-LEVEL</A><P>
Issue <A HREF="iss064.htm">COMPILED-FUNCTION-REQUIREMENTS</A><P>
Issue <A HREF="iss195.htm">IN-PACKAGE-FUNCTIONALITY</A><P>
Issue <A HREF="iss219.htm">LOCALLY-TOP-LEVEL</A><P>
<B>Category:</B> CLARIFICATION/CHANGE<P>
<B>Edit History:</B> 06-May-88, Version 1 by Sandra Loosemore<P>
16-Dec-88, Version 2 by Loosemore (alternate direction)<P>
30-Dec-88, Version 3 by Loosemore (minor wording changes)<P>
07-Jan-89, Version 4 by Loosemore (update discussion)<P>
09-Feb-89, Version 5 by Pitman and Moon (some major changes)<P>
09-Mar-89, Version 6 by Loosemore (clean up wording)<P>
22-Mar-89, Version 7 by Loosemore (order of processing)<P>
<B>Status:</B> Ready for release<P>
<P>
<B>Problem Description:<P>
</B><P>
The current description of how the compiler should handle <A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A><P>
only makes sense when it appears as a top-level form in the file being<P>
compiled. Is it legitimate for <A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> to appear in non-top-level<P>
locations? Even if it is legitimate, what does it mean?<P>
<P>
Another issue, referred to here as ``the <A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> shadowing problem,''<P>
is that some people have complained that shadowing the symbols <A REL=DEFINITION HREF="../Body/f_eval.htm#eval"><B>EVAL</B></A>,<P>
<A REL=DEFINITION HREF="../Body/f_cmp.htm#compile"><B>COMPILE</B></A>, or <A REL=DEFINITION HREF="../Body/f_load.htm#load"><B>LOAD</B></A> means that you have to also either shadow <A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A><P>
and define it to recognize the new symbol, or else you must resign<P>
yourself to writing (<A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> (... LISP:EVAL ...) ...),etc. all over.<P>
While the goal here is not to solve this problem, it might be possible<P>
to solve both problems at once.<P>
<P>
There are two proposals presented here, GENERALIZE-EVAL and<P>
GENERALIZE-EVAL-NEW-KEYWORDS.<P>
<P>
<P>
<B>Background/Analysis:<P>
</B><P>
The proposal which follows was constructed with the following goals<P>
in mind:<P>
<P>
1. The lexical and dynamic environment for the <A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> body should<P>
be the same for each situation. That is, the body should ``mean<P>
the same thing'' regardless of which situation is being processed.<P>
<P>
2. The evaluation context for <A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> should be the current<P>
lexical environment.<P>
<P>
3. At execution time, <A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> should always return the result of<P>
its last form if execution of the body occurred, or <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A> if the<P>
body was not executed.<P>
<P>
4. If a top-level <A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> has a <A REL=DEFINITION HREF="../Body/f_load.htm#load"><B>LOAD</B></A> keyword, its body should <P>
inherit top-level-ness during normal processing. This permits the<P>
use of (<A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> (<A REL=DEFINITION HREF="../Body/f_eval.htm#eval"><B>EVAL</B></A> <A REL=DEFINITION HREF="../Body/f_cmp.htm#compile"><B>COMPILE</B></A> <A REL=DEFINITION HREF="../Body/f_load.htm#load"><B>LOAD</B></A>) ...) at top-level to mean<P>
simply &quot;Do whatever would normally be done for this body, but<P>
also do something at compile time.&quot; This, in turn, will later be<P>
the key to allowing defining forms to be usefully described in<P>
terms of <A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A>.<P>
<P>
5. Non-top-level expressions should have no effect until they are<P>
executed. This is the key to making sure that any necessary<P>
environment is present. Since the <A REL=DEFINITION HREF="../Body/f_cmp.htm#compile"><B>COMPILE</B></A> keyword forces effects<P>
to occur earlier than execution time, it follows from this that<P>
any correct solution must not allow the <A REL=DEFINITION HREF="../Body/f_cmp.htm#compile"><B>COMPILE</B></A> keyword to have<P>
an effect at other than top-level.<P>
<P>
To accomplish these goals, we formulated the following model:<P>
<P>
The purpose of <A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> is to accomodate the fact that some of the<P>
semantic processing of an expression may usefully be partitioned<P>
between compile time and run time in some circumstances.<P>
<P>
(<A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> (<A REL=DEFINITION HREF="../Body/f_eval.htm#eval"><B>EVAL</B></A>) &lt;code&gt;)<P>
describes a general technique for accomplishing some particular goal<P>
at normal program execution time. However, the pair of expressions<P>
(<A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> (<A REL=DEFINITION HREF="../Body/f_cmp.htm#compile"><B>COMPILE</B></A>) &lt;code-A&gt;)<P>
(<A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> (<A REL=DEFINITION HREF="../Body/f_load.htm#load"><B>LOAD</B></A>) &lt;code-B&gt;)<P>
can be used to describe an alternate technique for implementing part<P>
of the effect (A) at compile-time, and part of the effect (B) at<P>
load-time.<P>
<P>
<P>
<B>Proposal (EVAL-WHEN-NON-TOP-LEVEL:GENERALIZE-EVAL):<P>
</B><P>
Replace the description of <A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> with the following:<P>
<P>
<A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> ({situation}*) {form}* [Special Form]<P>
<P>
The body of an <A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> form is processed as an implicit <A REL=DEFINITION HREF="../Body/s_progn.htm#progn"><B>PROGN</B></A>, but<P>
only in the situations listed. Each SITUATION must be a symbol,<P>
either <A REL=DEFINITION HREF="../Body/f_cmp.htm#compile"><B>COMPILE</B></A>, <A REL=DEFINITION HREF="../Body/f_load.htm#load"><B>LOAD</B></A>, or <A REL=DEFINITION HREF="../Body/f_eval.htm#eval"><B>EVAL</B></A>.<P>
<P>
The use of <A REL=DEFINITION HREF="../Body/f_cmp.htm#compile"><B>COMPILE</B></A> and <A REL=DEFINITION HREF="../Body/f_load.htm#load"><B>LOAD</B></A> controls whether and when processing<P>
occurs for top-level forms. The use of <A REL=DEFINITION HREF="../Body/f_eval.htm#eval"><B>EVAL</B></A> controls whether<P>
processing occurs for non-top-level forms.<P>
<P>
The <A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> construct may be more precisely understood in terms of<P>
a model of how the file compiler, <A REL=DEFINITION HREF="../Body/f_cmp_fi.htm#compile-file"><B>COMPILE-FILE</B></A>, processes forms in a<P>
file to be compiled.<P>
<P>
Successive forms are read from the file by the file compiler using <P>
<A REL=DEFINITION HREF="../Body/f_rd_rd.htm#read"><B>READ</B></A>. These top-level forms are normally processed in what we call<P>
`not-compile-time' mode. There is one other mode, called <P>
`compile-time-too' mode, which can come into play for top-level<P>
forms. The <A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> special form is used to annotate a program<P>
in a way that allows the program doing the processing to select<P>
the appropriate mode.<P>
<P>
Processing of top-level forms in the file compiler works as follows:<P>
<P>
* If the form is a macro call, it is expanded and the result is<P>
processed as a top-level form in the same processing mode<P>
(compile-time-too or not-compile-time).<P>
<P>
* If the form is a <A REL=DEFINITION HREF="../Body/s_progn.htm#progn"><B>PROGN</B></A> form, each of its body forms is<P>
sequentially processed as top-level forms in the same processing<P>
mode.<P>
<P>
* If the form is a COMPILER-LET, <A REL=DEFINITION HREF="../Body/s_flet_.htm#macrolet"><B>MACROLET</B></A>, or <A REL=DEFINITION HREF="../Body/s_symbol.htm#symbol-macrolet"><B>SYMBOL-MACROLET</B></A>,<P>
the file compiler makes the appropriate bindings and recursively<P>
processes the body forms as an implicit top-level <A REL=DEFINITION HREF="../Body/s_progn.htm#progn"><B>PROGN</B></A> with those <P>
bindings in effect, in the same processing mode.<P>
<P>
* If the form is an <A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> form, it is handled according to<P>
the following table:<P>
<P>
<A REL=DEFINITION HREF="../Body/f_cmp.htm#compile"><B>COMPILE</B></A> <A REL=DEFINITION HREF="../Body/f_load.htm#load"><B>LOAD</B></A> <A REL=DEFINITION HREF="../Body/f_eval.htm#eval"><B>EVAL</B></A> compile-time-too Action<P>
<P>
Yes Yes -- -- Process body in compile-time-too mode<P>
No Yes Yes Yes Process body in compile-time-too mode<P>
No Yes Yes No Process body in not-compile-time mode<P>
No Yes No -- Process body in not-compile-time mode<P>
Yes No -- -- Evaluate body<P>
No No Yes Yes Evaluate body<P>
No No Yes No do nothing<P>
No No No -- do nothing<P>
<P>
&quot;Process body&quot; means to process the body as an implicit top-level<P>
<A REL=DEFINITION HREF="../Body/s_progn.htm#progn"><B>PROGN</B></A>. &quot;Evaluate body&quot; means to evaluate the body forms as in<P>
implicit <A REL=DEFINITION HREF="../Body/s_progn.htm#progn"><B>PROGN</B></A> in the dynamic execution context of the compiler and<P>
in the lexical environment in which the <A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> appears.<P>
<P>
* Otherwise, the form is a top-level form that is not one of the<P>
special cases. If in compile-time-too mode, the compiler first<P>
evaluates the form and then performs normal compiler processing<P>
on it. If in not-compile-time mode, only normal compiler<P>
processing is performed. [The nature of this processing is<P>
defined more precisely in issue <A HREF="iss064.htm">COMPILED-FUNCTION-REQUIREMENTS</A>.]<P>
Any subforms are treated as non-top-level forms.<P>
<P>
Note that top-level forms are guaranteed to be processed in the order<P>
in which they textually appear in the file, and that each top-level<P>
form read by the compiler is processed before the next is read.<P>
However, the order of processing (including, in particular, macro<P>
expansion) of subforms that are not top-level forms is unspecified.<P>
<P>
For an <A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> form that is not a top-level form in the file compiler<P>
(that is, one of: in <A REL=DEFINITION HREF="../Body/s_the.htm#the"><B>the</B></A> interpreter; in COMPILE; <A REL=DEFINITION HREF="../Body/a_or.htm#or"><B>or</B></A> in <A REL=DEFINITION HREF="../Body/s_the.htm#the"><B>the</B></A> file<P>
compiler but not at top-level), if the <A REL=DEFINITION HREF="../Body/f_eval.htm#eval"><B>EVAL</B></A> situation is specified,<P>
its body is treated as an implicit <A REL=DEFINITION HREF="../Body/s_progn.htm#progn"><B>PROGN</B></A>. Otherwise, the <A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A><P>
form returns <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>.<P>
<P>
<P>
Clarifications/Consequences:<P>
<P>
The following effects are logical consequences of the above proposal:<P>
<P>
* It is never the case that the execution of a single <A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A><P>
expression will execute the body code more than once.<P>
<P>
* The keyword `<A REL=DEFINITION HREF="../Body/f_eval.htm#eval"><B>EVAL</B></A>' is a misnomer because execution of<P>
the body need not be done by <A REL=DEFINITION HREF="../Body/f_eval.htm#eval"><B>EVAL</B></A>. In compiled code, such as<P>
(<A REL=DEFINITION HREF="../Body/m_defun.htm#defun"><B>DEFUN</B></A> FOO () (<A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> (<A REL=DEFINITION HREF="../Body/f_eval.htm#eval"><B>EVAL</B></A>) (<A REL=DEFINITION HREF="../Body/f_wr_pr.htm#print"><B>PRINT</B></A> 'FOO)))<P>
the call to <A REL=DEFINITION HREF="../Body/f_wr_pr.htm#print"><B>PRINT</B></A> should be compiled.<P>
<P>
* Macros intended for use in top-level forms should arrange for all<P>
side-effects to be done by the forms in the macro expansion.<P>
The macro-expander itself should not do the side-effects.<P>
<P>
Wrong: (<A REL=DEFINITION HREF="../Body/m_defmac.htm#defmacro"><B>defmacro</B></A> foo ()<P>
(really-foo)<P>
`(really-foo))<P>
<P>
Right: (<A REL=DEFINITION HREF="../Body/m_defmac.htm#defmacro"><B>defmacro</B></A> foo ()<P>
`(<A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>eval-when</B></A> (compile <A REL=DEFINITION HREF="../Body/f_eval.htm#eval"><B>eval</B></A> load) (really-foo)))<P>
<P>
Adherence to this convention will mean that such macros will behave<P>
intuitively when placed in non-top-level positions.<P>
<P>
* Placing a variable binding around an <A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> reliably captures the<P>
binding because the `compile-time-too' mode cannot occur (because <P>
introducing a variable binding would mean we were not at top level).<P>
For example,<P>
<P>
(<A REL=DEFINITION HREF="../Body/s_let_l.htm#let"><B>LET</B></A> ((X 3))<P>
(<A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> (<A REL=DEFINITION HREF="../Body/f_eval.htm#eval"><B>EVAL</B></A> <A REL=DEFINITION HREF="../Body/f_load.htm#load"><B>LOAD</B></A> <A REL=DEFINITION HREF="../Body/f_cmp.htm#compile"><B>COMPILE</B></A>) (<A REL=DEFINITION HREF="../Body/f_wr_pr.htm#print"><B>PRINT</B></A> X)))<P>
<P>
will print 3 at execution [load] time, and will not print anything at<P>
compile time. This is important so that expansions of <A REL=DEFINITION HREF="../Body/m_defun.htm#defun"><B>DEFUN</B></A> and <P>
<A REL=DEFINITION HREF="../Body/m_defmac.htm#defmacro"><B>DEFMACRO</B></A> can be done in terms of <A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> and can correctly capture<P>
the lexical environment.<P>
<P>
(<A REL=DEFINITION HREF="../Body/m_defun.htm#defun"><B>DEFUN</B></A> BAR (X) (<A REL=DEFINITION HREF="../Body/m_defun.htm#defun"><B>DEFUN</B></A> FOO () (+ X 3)))<P>
<P>
might expand into<P>
<P>
(<A REL=DEFINITION HREF="../Body/m_defun.htm#defun"><B>DEFUN</B></A> BAR (X) <P>
(<A REL=DEFINITION HREF="../Body/s_progn.htm#progn"><B>PROGN</B></A> (<A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> (<A REL=DEFINITION HREF="../Body/f_cmp.htm#compile"><B>COMPILE</B></A>) <P>
(COMPILER::NOTICE-FUNCTION-DEFINITION 'FOO '(X)))<P>
(<A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> (<A REL=DEFINITION HREF="../Body/f_eval.htm#eval"><B>EVAL</B></A> <A REL=DEFINITION HREF="../Body/f_load.htm#load"><B>LOAD</B></A>)<P>
(<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> (<A REL=DEFINITION HREF="../Body/f_symb_1.htm#symbol-function"><B>SYMBOL-FUNCTION</B></A> 'FOO) #'(<A REL=DEFINITION HREF="../Body/a_lambda.htm#lambda"><B>LAMBDA</B></A> () (+ X 3))))))<P>
<P>
which would be treated the same as<P>
<P>
(<A REL=DEFINITION HREF="../Body/m_defun.htm#defun"><B>DEFUN</B></A> BAR (X) <P>
(<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> (<A REL=DEFINITION HREF="../Body/f_symb_1.htm#symbol-function"><B>SYMBOL-FUNCTION</B></A> 'FOO) #'(<A REL=DEFINITION HREF="../Body/a_lambda.htm#lambda"><B>LAMBDA</B></A> () (+ X 3))))<P>
<P>
by the above rules.<P>
<P>
<P>
Test Cases:<P>
<P>
;; #1: The <A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> in this case is not at top-level, so only the <A REL=DEFINITION HREF="../Body/f_eval.htm#eval"><B>EVAL</B></A><P>
;; keyword is considered. At compile time, this has no effect.<P>
;; At load time (if the <A REL=DEFINITION HREF="../Body/s_let_l.htm#let"><B>LET</B></A> is at top level), or at execution time<P>
;; (if the <A REL=DEFINITION HREF="../Body/s_let_l.htm#let"><B>LET</B></A> is embedded in some other form which does not execute<P>
;; until later) this sets (<A REL=DEFINITION HREF="../Body/f_symb_1.htm#symbol-function"><B>SYMBOL-FUNCTION</B></A> 'FOO1) to a function which<P>
;; returns 1.<P>
<P>
(<A REL=DEFINITION HREF="../Body/s_let_l.htm#let"><B>LET</B></A> ((X 1))<P>
(<A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> (<A REL=DEFINITION HREF="../Body/f_eval.htm#eval"><B>EVAL</B></A> <A REL=DEFINITION HREF="../Body/f_load.htm#load"><B>LOAD</B></A> <A REL=DEFINITION HREF="../Body/f_cmp.htm#compile"><B>COMPILE</B></A>)<P>
(<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> (<A REL=DEFINITION HREF="../Body/f_symb_1.htm#symbol-function"><B>SYMBOL-FUNCTION</B></A> 'FOO1) #'(<A REL=DEFINITION HREF="../Body/a_lambda.htm#lambda"><B>LAMBDA</B></A> () X))))<P>
<P>
;; #2: If this expression occurs at the top-level of a file to be compiled,<P>
;; it has BOTH a compile time <A REL=DEFINITION HREF="../Body/a_and.htm#and"><B>AND</B></A> a load-time effect of setting<P>
;; (<A REL=DEFINITION HREF="../Body/f_symb_1.htm#symbol-function"><B>SYMBOL-FUNCTION</B></A> 'FOO2) to a function which returns 2.<P>
<P>
(<A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> (<A REL=DEFINITION HREF="../Body/f_eval.htm#eval"><B>EVAL</B></A> <A REL=DEFINITION HREF="../Body/f_load.htm#load"><B>LOAD</B></A> <A REL=DEFINITION HREF="../Body/f_cmp.htm#compile"><B>COMPILE</B></A>)<P>
(<A REL=DEFINITION HREF="../Body/s_let_l.htm#let"><B>LET</B></A> ((X 2))<P>
(<A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> (<A REL=DEFINITION HREF="../Body/f_eval.htm#eval"><B>EVAL</B></A> <A REL=DEFINITION HREF="../Body/f_load.htm#load"><B>LOAD</B></A> <A REL=DEFINITION HREF="../Body/f_cmp.htm#compile"><B>COMPILE</B></A>)<P>
(<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> (<A REL=DEFINITION HREF="../Body/f_symb_1.htm#symbol-function"><B>SYMBOL-FUNCTION</B></A> 'FOO2) #'(<A REL=DEFINITION HREF="../Body/a_lambda.htm#lambda"><B>LAMBDA</B></A> () X)))))<P>
<P>
;; #3: If this expression occurs at the top-level of a file to be compiled,<P>
;; it has BOTH a compile time <A REL=DEFINITION HREF="../Body/a_and.htm#and"><B>AND</B></A> a load-time effect of setting the<P>
;; function cell of FOO3 to a function which returns 3.<P>
<P>
(<A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> (<A REL=DEFINITION HREF="../Body/f_eval.htm#eval"><B>EVAL</B></A> <A REL=DEFINITION HREF="../Body/f_load.htm#load"><B>LOAD</B></A> <A REL=DEFINITION HREF="../Body/f_cmp.htm#compile"><B>COMPILE</B></A>)<P>
(<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> (<A REL=DEFINITION HREF="../Body/f_symb_1.htm#symbol-function"><B>SYMBOL-FUNCTION</B></A> 'FOO3) #'(<A REL=DEFINITION HREF="../Body/a_lambda.htm#lambda"><B>LAMBDA</B></A> () 3)))<P>
<P>
;; #4: This always does nothing. It simply returns <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>.<P>
<P>
(<A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> (<A REL=DEFINITION HREF="../Body/f_cmp.htm#compile"><B>COMPILE</B></A>)<P>
(<A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> (<A REL=DEFINITION HREF="../Body/f_cmp.htm#compile"><B>COMPILE</B></A>) <P>
(<A REL=DEFINITION HREF="../Body/f_wr_pr.htm#print"><B>PRINT</B></A> 'FOO4)))<P>
<P>
;; #5: If this form occurs at top-level of a file to be compiled, FOO5 is<P>
;; printed at compile time. If this form occurs in a non-top-level<P>
;; position, nothing is printed at compile time. Regardless of context,<P>
;; nothing is ever printed at load time or execution time.<P>
<P>
(<A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> (<A REL=DEFINITION HREF="../Body/f_cmp.htm#compile"><B>COMPILE</B></A>) <P>
(<A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> (<A REL=DEFINITION HREF="../Body/f_eval.htm#eval"><B>EVAL</B></A>)<P>
(<A REL=DEFINITION HREF="../Body/f_wr_pr.htm#print"><B>PRINT</B></A> 'FOO5)))<P>
<P>
;; #6: If this form occurs at top-level of a file to be compiled, FOO6 is<P>
;; printed at compile time. If this form occurs in a non-top-level<P>
;; position, nothing is printed at compile time. Regardless of context,<P>
;; nothing is ever printed at load time or execution time.<P>
<P>
(<A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> (<A REL=DEFINITION HREF="../Body/f_eval.htm#eval"><B>EVAL</B></A> <A REL=DEFINITION HREF="../Body/f_load.htm#load"><B>LOAD</B></A>)<P>
(<A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> (<A REL=DEFINITION HREF="../Body/f_cmp.htm#compile"><B>COMPILE</B></A>)<P>
(<A REL=DEFINITION HREF="../Body/f_wr_pr.htm#print"><B>PRINT</B></A> 'FOO6)))<P>
<P>
Rationale:<P>
<P>
This is compatible with any guarantees made by CLtL, and extends the<P>
behavior usefully to non-top-level situations.<P>
<P>
This gives a useful meaning to <A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> that supports useful and<P>
predictable behavior if defining macros are used in a non-top-level<P>
situation.<P>
<P>
The constraints on the order in which top-level forms are processed<P>
ensure that the compile-time effects of defining macros and EVAL-WHENs<P>
at the beginning of the file are visible during the processing of<P>
forms that appear later in the file, which is what most users expect.<P>
Leaving the order of processing of non-top-level forms unspecified<P>
allows the compiler to perform certain kinds of transformations that<P>
change the textual order of subforms. Users should not depend on <P>
side-effects from macros that <A REL=DEFINITION HREF="../Body/f_provid.htm#require"><B>require</B></A> them to be expanded in any<P>
particular order.<P>
<P>
<P>
<B>Proposal (EVAL-WHEN-NON-TOP-LEVEL:GENERALIZE-EVAL-NEW-KEYWORDS):<P>
</B><P>
As in GENERALIZE-EVAL, but rename the <A REL=DEFINITION HREF="../Body/f_eval.htm#eval"><B>EVAL</B></A> keyword to :EXECUTE,<P>
the <A REL=DEFINITION HREF="../Body/f_cmp.htm#compile"><B>COMPILE</B></A> keyword to :COMPILE-TOPLEVEL, and <A REL=DEFINITION HREF="../Body/f_load.htm#load"><B>LOAD</B></A> keyword to <P>
:LOAD-TOPLEVEL.<P>
<P>
Deprecate the use of keywords <A REL=DEFINITION HREF="../Body/f_eval.htm#eval"><B>EVAL</B></A>, <A REL=DEFINITION HREF="../Body/f_cmp.htm#compile"><B>COMPILE</B></A>, and <A REL=DEFINITION HREF="../Body/f_load.htm#load"><B>LOAD</B></A> to <A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A>.<P>
For compatibility, they are supported in <A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A><P>
at top-level, but their meaning is not defined elsewhere.<P>
<P>
Rationale:<P>
<P>
The fact that the situation keywords chosen are not the same as<P>
those now used means that the change can be added in a way that<P>
is truly upward compatible (not only with CLtL but with existing<P>
practice in implementations which have chosen to extend or `clarify'<P>
the definition given in CLtL) since the meaning of <A REL=DEFINITION HREF="../Body/f_eval.htm#eval"><B>EVAL</B></A>, <A REL=DEFINITION HREF="../Body/f_cmp.htm#compile"><B>COMPILE</B></A>,<P>
and <A REL=DEFINITION HREF="../Body/f_load.htm#load"><B>LOAD</B></A> in non-top-level situations (which was never spelled<P>
out in CLtL) can legitimately differ from the meaning of these<P>
new keywords.<P>
<P>
Using other names and/or the keyword package for the names of<P>
situations solves the <A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> shadowing problem.<P>
<P>
The name `execute' does not promote the confusion that the body of an<P>
<A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> must be executed only in the evaluator. It also does not<P>
promote the confusion that the body of an <A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A>, regardless of when<P>
executed, must run interpreted.<P>
<P>
The names `compile-toplevel' and `load-toplevel' emphasize the fact<P>
that these cases are not interesting in non-top-level positions.<P>
<P>
<P>
<B>Current Practice:<P>
</B><P>
In Symbolics Genera, the interpreter permits <A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> in non-top-level <P>
positions in a way that is compatible with this proposal but both the<P>
<A REL=DEFINITION HREF="../Body/f_cmp.htm#compile"><B>COMPILE</B></A> and <A REL=DEFINITION HREF="../Body/f_cmp_fi.htm#compile-file"><B>COMPILE-FILE</B></A> functions complain about <A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> in a<P>
non-top-level position.<P>
<P>
Both Lucid Common Lisp and Kyoto Common Lisp already interpret the<P>
<A REL=DEFINITION HREF="../Body/f_eval.htm#eval"><B>EVAL</B></A> keyword to mean &quot;execute&quot; in non-top-level situations. Both of<P>
these implementations also make (<A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> (<A REL=DEFINITION HREF="../Body/f_load.htm#load"><B>LOAD</B></A>) ...) suppress<P>
compile-time &quot;magic&quot; from defining macros such as <A REL=DEFINITION HREF="../Body/m_defmac.htm#defmacro"><B>DEFMACRO</B></A>.<P>
<P>
IIM describes its <A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> as:<P>
(<A REL=DEFINITION HREF="../Body/m_defmac.htm#defmacro"><B>defmacro</B></A> <A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>eval-when</B></A> (situations <A REL=DEFINITION HREF="../Body/03_dd.htm#AMbody"><B>&amp;body</B></A> body <A REL=DEFINITION HREF="../Body/03_dd.htm#AMenvironment"><B>&amp;environment</B></A> env)<P>
(<A REL=DEFINITION HREF="../Body/s_if.htm#if"><B>if</B></A> (<A REL=DEFINITION HREF="../Body/a_not.htm#not"><B>not</B></A> (compiler-environment-p env))<P>
(<A REL=DEFINITION HREF="../Body/m_when_.htm#when"><B>when</B></A> (<A REL=DEFINITION HREF="../Body/a_member.htm#member"><B>member</B></A> '<A REL=DEFINITION HREF="../Body/f_eval.htm#eval"><B>eval</B></A> situations) `(<A REL=DEFINITION HREF="../Body/s_progn.htm#progn"><B>progn</B></A> ,@body))<P>
(<A REL=DEFINITION HREF="../Body/s_progn.htm#progn"><B>progn</B></A><P>
(<A REL=DEFINITION HREF="../Body/m_when_.htm#when"><B>when</B></A> (<A REL=DEFINITION HREF="../Body/a_member.htm#member"><B>member</B></A> '<A REL=DEFINITION HREF="../Body/f_cmp.htm#compile"><B>compile</B></A> situations)<P>
(<A REL=DEFINITION HREF="../Body/s_if.htm#if"><B>if</B></A> (compiler-at-top-level-p env)<P>
(<A REL=DEFINITION HREF="../Body/f_mapc_.htm#mapc"><B>mapc</B></A> #'<A REL=DEFINITION HREF="../Body/f_eval.htm#eval"><B>eval</B></A> body)<P>
(<A REL=DEFINITION HREF="../Body/f_warn.htm#warn"><B>warn</B></A> &quot;Top-level form encountered at non-top-level.&quot;)))<P>
(<A REL=DEFINITION HREF="../Body/m_when_.htm#when"><B>when</B></A> (<A REL=DEFINITION HREF="../Body/a_member.htm#member"><B>member</B></A> '<A REL=DEFINITION HREF="../Body/f_load.htm#load"><B>load</B></A> situations) `(<A REL=DEFINITION HREF="../Body/s_progn.htm#progn"><B>progn</B></A> ,@body)))))<P>
Note that the interpretation of the <A REL=DEFINITION HREF="../Body/f_eval.htm#eval"><B>EVAL</B></A> situation and the nesting<P>
behavior is different.<P>
<P>
<P>
<B>Cost to Implementors:<P>
</B><P>
The actual change to <A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> in both cases is probably fairly<P>
localized and straightforward to make in most or all implementations.<P>
<P>
The second-order costs of proposal GENERALIZE-EVAL will vary depending<P>
on whether existing implementations have extended the definition of<P>
<A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> in incompatible ways. If an implementation has made such<P>
extensions, there may be user and system code which depends on them<P>
and the cost of converting that code may be non-trivial. There is<P>
presumably also documentation impact.<P>
<P>
Proposal GENERALIZE-EVAL-NEW-KEYWORDS avoids most or all of the <P>
second-order costs of proposal GENERALIZE-EVAL.<P>
<P>
The compiler processing for top-level forms might be implemented <P>
something like:<P>
<P>
;;; Forms read by the file compiler are passed to PROCESS-TOP-LEVEL-FORM<P>
;;; with a env compile-time-too both <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>.<P>
<P>
(<A REL=DEFINITION HREF="../Body/m_defun.htm#defun"><B>defun</B></A> process-top-level-form (form env compile-time-too)<P>
(<A REL=DEFINITION HREF="../Body/s_setq.htm#setq"><B>setq</B></A> form (<A REL=DEFINITION HREF="../Body/f_mexp_.htm#macroexpand"><B>macroexpand</B></A> form env))<P>
(<A REL=DEFINITION HREF="../Body/m_cond.htm#cond"><B>cond</B></A> ((<A REL=DEFINITION HREF="../Body/a_not.htm#not"><B>not</B></A> (<A REL=DEFINITION HREF="../Body/f_consp.htm#consp"><B>consp</B></A> form))<P>
<A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>nil</B></A>)<P>
((<A REL=DEFINITION HREF="../Body/f_eq.htm#eq"><B>eq</B></A> (<A REL=DEFINITION HREF="../Body/f_car_c.htm#car"><B>car</B></A> form) '<A REL=DEFINITION HREF="../Body/s_progn.htm#progn"><B>progn</B></A>)<P>
(<A REL=DEFINITION HREF="../Body/m_dolist.htm#dolist"><B>dolist</B></A> (f (<A REL=DEFINITION HREF="../Body/f_car_c.htm#cdr"><B>cdr</B></A> form))<P>
(process-top-level-form f env compile-time-too)))<P>
((<A REL=DEFINITION HREF="../Body/f_eq.htm#eq"><B>eq</B></A> (<A REL=DEFINITION HREF="../Body/f_car_c.htm#car"><B>car</B></A> form) 'compiler-let)<P>
(process-compiler-let form env compile-time-too))<P>
((<A REL=DEFINITION HREF="../Body/f_eq.htm#eq"><B>eq</B></A> (<A REL=DEFINITION HREF="../Body/f_car_c.htm#car"><B>car</B></A> form) '<A REL=DEFINITION HREF="../Body/s_flet_.htm#macrolet"><B>macrolet</B></A>)<P>
(process-macrolet form env compile-time-too))<P>
((<A REL=DEFINITION HREF="../Body/f_eq.htm#eq"><B>eq</B></A> (<A REL=DEFINITION HREF="../Body/f_car_c.htm#car"><B>car</B></A> form) '<A REL=DEFINITION HREF="../Body/s_symbol.htm#symbol-macrolet"><B>symbol-macrolet</B></A>)<P>
(process-symbol-macrolet form env compile-time-too))<P>
((<A REL=DEFINITION HREF="../Body/f_eq.htm#eq"><B>eq</B></A> (<A REL=DEFINITION HREF="../Body/f_car_c.htm#car"><B>car</B></A> form) '<A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>eval-when</B></A>)<P>
(process-eval-when form env compile-time-too))<P>
(t<P>
(<A REL=DEFINITION HREF="../Body/s_if.htm#if"><B>if</B></A> compile-time-too<P>
(internal-eval form env))<P>
(compile-form form env))<P>
))<P>
<P>
(<A REL=DEFINITION HREF="../Body/m_defun.htm#defun"><B>defun</B></A> process-eval-when (form env compile-time-too)<P>
(<A REL=DEFINITION HREF="../Body/s_let_l.htm#letST"><B>let*</B></A> ((situations (<A REL=DEFINITION HREF="../Body/f_car_c.htm#cadr"><B>cadr</B></A> form))<P>
(body (<A REL=DEFINITION HREF="../Body/f_car_c.htm#cddr"><B>cddr</B></A> form))<P>
(compile-p (<A REL=DEFINITION HREF="../Body/a_member.htm#member"><B>member</B></A> '<A REL=DEFINITION HREF="../Body/f_cmp.htm#compile"><B>compile</B></A> situations))<P>
(load-p (<A REL=DEFINITION HREF="../Body/a_member.htm#member"><B>member</B></A> '<A REL=DEFINITION HREF="../Body/f_load.htm#load"><B>load</B></A> situations))<P>
(eval-p (<A REL=DEFINITION HREF="../Body/a_member.htm#member"><B>member</B></A> '<A REL=DEFINITION HREF="../Body/f_eval.htm#eval"><B>eval</B></A> situations)))<P>
(<A REL=DEFINITION HREF="../Body/m_cond.htm#cond"><B>cond</B></A> ((<A REL=DEFINITION HREF="../Body/a_or.htm#or"><B>or</B></A> (<A REL=DEFINITION HREF="../Body/a_and.htm#and"><B>and</B></A> compile-p load-p)<P>
(<A REL=DEFINITION HREF="../Body/a_and.htm#and"><B>and</B></A> eval-p load-p compile-time-too))<P>
(process-top-level-form `(<A REL=DEFINITION HREF="../Body/s_progn.htm#progn"><B>progn</B></A> ,@body) env t))<P>
(load-p<P>
(process-top-level-form `(<A REL=DEFINITION HREF="../Body/s_progn.htm#progn"><B>progn</B></A> ,@body) env <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>nil</B></A>))<P>
((<A REL=DEFINITION HREF="../Body/a_or.htm#or"><B>or</B></A> compile-p<P>
(<A REL=DEFINITION HREF="../Body/a_and.htm#and"><B>and</B></A> eval-p compile-time-too))<P>
(<A REL=DEFINITION HREF="../Body/m_dolist.htm#dolist"><B>dolist</B></A> (f body)<P>
(internal-eval f env)))<P>
(t<P>
<A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>nil</B></A>))))<P>
<P>
;;; PROCESS-COMPILER-LET, PROCESS-MACROLET, and PROCESS-SYMBOL-MACROLET<P>
;;; do the obvious things.<P>
;;; INTERNAL-EVAL evaluates &quot;form&quot; in lexical environment &quot;env&quot;.<P>
<P>
<P>
<B>Cost to Users:<P>
</B><P>
Technically, none. Either proposal is technically upward compatible<P>
with CLtL.<P>
<P>
Proposal GENERALIZE-EVAL might force some extended implementations to<P>
change incompatibly. As such, some users who depend on <P>
implementation-dependent extensions might have to adjust their code<P>
somewhat to deal with those changes.<P>
<P>
Proposal GENERALIZE-EVAL-NEW-KEYWORDS does not force implementations<P>
to change incompatibly, so has no forced impact on users.<P>
<P>
<B>Cost of Non-Adoption:<P>
</B><P>
<A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> is a mess. Using it as the low-level substrate into which<P>
defining macros should expand, and guaranteeing any predictable effects<P>
of those macros in non-top-level situations is currently difficult and<P>
would continue to be so in the absence of some resolution on this issue.<P>
<P>
<B>Benefits:<P>
</B><P>
The costs of non-adoption would be avoided: it would be possible to<P>
use <A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> in many situations where it cannot currently be used<P>
reliably.<P>
<P>
The portability of many existing tools which use <A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> internally<P>
in macros will be enhanced.<P>
<P>
<B>Aesthetics:<P>
</B><P>
This generalization of the meaning makes the purpose and uses of <P>
<A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> less mysterious. In that sense, aesthetics are simplified<P>
somewhat.<P>
<P>
<P>
<B>Discussion:<P>
</B><P>
The cleanup issue <A HREF="iss219.htm">LOCALLY-TOP-LEVEL</A> would make <A REL=DEFINITION HREF="../Body/s_locall.htm#locally"><B>LOCALLY</B></A> also &quot;pass<P>
through&quot; top-level-ness to its body. The reason why that is not <P>
addressed in this issue is that it involves making <A REL=DEFINITION HREF="../Body/s_locall.htm#locally"><B>LOCALLY</B></A> a special<P>
form.<P>
<P>
Pitman and Moon don't care whether we say `top level,' `top-level,' or<P>
`toplevel.' The spelling choices in this writeup are arbitrary. If<P>
necessary, the proposal GENERALIZE-EVAL-NEW-KEYWORDS could be amended<P>
to propose :COMPILE-TOP-LEVEL, etc.<P>
<P>
Pitman, Moon, and Bob Laddaga (a Symbolics Cloe implementor) support<P>
both of these proposals. Pitman and Laddaga have a preference for<P>
GENERALIZE-EVAL-NEW-KEYWORDS. Moon is neutral about which should be<P>
preferred.<P>
<P>
Sandra Loosemore says:<P>
I still feel somewhat uncomfortable with the definition of <A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A><P>
presented here, mostly because its nesting behavior is so unintuitive<P>
(as in test case number 6). We have also had a hard time in deciding<P>
what the term &quot;top-level&quot; really means; the definition presented here<P>
is rather arbitrary. However, since we have run out of time in which<P>
to come up with acceptable alternatives, I'm willing to go along with<P>
proposal GENERALIZE-EVAL. It is compatible with the description in<P>
CLtL but presented in a more coherent way, and I think it is an<P>
improvement. On the other hand, I don't really like the idea of<P>
changing the names of the keywords; if we are going to make an<P>
incompatible change, the right thing to do would be to throw out<P>
<A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> entirely and start from scratch.<P>
<P>
Treating <A REL=DEFINITION HREF="../Body/s_flet_.htm#macrolet"><B>MACROLET</B></A> and <A REL=DEFINITION HREF="../Body/s_symbol.htm#symbol-macrolet"><B>SYMBOL-MACROLET</B></A> (and possibly <A REL=DEFINITION HREF="../Body/s_locall.htm#locally"><B>LOCALLY</B></A>) <P>
complicates the treatment of top-level DEFMACROs and other<P>
defining macros that cause functions to be created at compile-time<P>
(because <A REL=DEFINITION HREF="../Body/s_the.htm#the"><B>the</B></A> lexical environment <A REL=DEFINITION HREF="../Body/s_the.htm#the"><B>the</B></A> functions are defined in may<P>
not be null). See issue <A HREF="iss104.htm">DEFINING-MACROS-NON-TOP-LEVEL</A> for details.-------<P>
<P>
</PRE>
<HR>
<A REL=NAVIGATOR HREF="../Front/StartPts.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Starting Points]" SRC="../Graphics/StartPts.gif" ALIGN=Bottom></A><A REL=TOC HREF="../Front/Contents.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Contents]" SRC="../Graphics/Contents.gif" ALIGN=Bottom></A><A REL=INDEX HREF="../Front/X_Master.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Index]" SRC="../Graphics/Index.gif" ALIGN=Bottom></A><A REL=INDEX HREF="../Front/X_Symbol.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Symbols]" SRC="../Graphics/Symbols.gif" ALIGN=Bottom></A><A REL=GLOSSARY HREF="../Body/26_a.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Glossary]" SRC="../Graphics/Glossary.gif" ALIGN=Bottom></A><A HREF="../Front/X3J13Iss.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Issues]" SRC="../Graphics/Issues.gif" ALIGN=Bottom></A><BR>
<A REL=COPYRIGHT HREF="../Front/Help.htm#Legal"><I>Copyright 1996-2005, LispWorks Ltd. All rights reserved.</I></A><P>
</BODY>
</HTML>