. navigate
XREF    Page 8 left arrow
right arrow Page 10    XREF

LISP Pointers
Volume I, Number 1
April-May 1987

page 9

Prev Article               Start of This Article                Next Article

not compiling; the compiler is just another instance of file processing programs. On the other hand, sometimes the idiom is used to execute code needed by the compiler, as when a function is defined that is called by a macro later in the file. In the COMMON LISP standard as it exists today, however, there is no read context for eval-when.

The problem for a code analysis program9 is to determine when to evaluate [implicit] eval-when forms and when to merely analyze them. For example, if set-macro-character is called in the body of a function, it should not be evaluated, but what if it were lexically inside a let in a source file but outside any defun? Should calls to macros that expand into eval-when forms be evaluated? `

Generally, compilers (and other code analyzers) will resolve the ambiguity by distinguishing between "top-level" forms and "embedded" forms. Top-level [implicit] eval-when forms are evaluated at analysis (i.e., compile) time; embedded forms are only processed as code. XREF takes a common denominator approach: Forms defining named program objects -- functions, macros, variables -- set up a context in which lexically enclosed forms are embedded; anything outside is considered top-level.

The top-level forms distinction is important for writers of portable programs, since it concerns the reader and compiler directives that are part of portable COMMON LISP. Since it is a source of ambiguity, the following recommendation is in order:

Portability Tip 2:
Assume that nothing is evaluated by the compiler unless it is a top-level form enclosed in eval-when, except for those listed on page 182 of CLtL. Explicitly wrap (eval-when (compile eval load) form) around any form that needs to be evaluated before subsequent forms can be processed. Only use eval-when outside of the lexical contours of function and macro definitions; eval-when in embedded forms is ambiguous and therefore not portable.

5    Compiler Side-effects

Implicit eval-when forms such as in-package can cause permanent side effects to the environment in which they are executed. For example, in-package can create a new package or change its relationship to other packages. Other forms produce side-effects used by the compiler (or XREF) to process later forms. For instance, macro definitions must be "remembered" by the compiler so that subsequent forms that call the macros can be properly expanded. Other "compiler side-effects" include defsetf, defstruct, deftype, and calls to proclaim. Any code enclosed in (eval-when (compile . . . ) code) can change the state of the environment in which the compiler executes.

Evaluating arbitrary user code in the current LISP environment can be dangerous, because it may break existing code by redeiining existing functions and macros, altering the properties of symbols, or changing the state of the reader.10 It can also change the behavior of functions

9    including language-specific editors, which have to know how to process package-manipulating forms.

10    A common mistake made by overzealous novice programmers is to define reader macros and modify the readtable in the top level of a file; when the compiler processes that file, Lisp's reader is permanently altered, sometimes beyond repair!

Page Left left arrow         
right arrow Page Right
Vol. I, No. 1
Table of Contents

Home   Favorites   Computers   Map

IME logo Copyright © 2009, Mary S. Van Deusen