eval-when (original) (raw)

ANSI Common Lisp 3 Evaluation and Compilation 3.8 Dictionary Evaluation and Compilation

3.8.5 eval-when Special Operator

Syntax:

eval-when ({situation}*) {form}* {result}*

Arguments and Values:

situation - One of the symbols :compile-toplevel,:load-toplevel,:execute,compile,load, oreval.

The use of eval, compile, and load is deprecated.

forms - an implicit progn.

results - the values of the forms if they are executed, or nil if they are not.

Description:

The body of an eval-when form is processed as an implicit progn, but only in the situations listed.

The use of the situations :compile-toplevel (or compile) and:load-toplevel (or load) controls whether and when _evaluation_occurs when eval-when appears as a top level form in code processed by compile-file. See Section 3.2.3 File Compilation.

The use of the situation :execute (or eval) controls whether evaluation occurs for other eval-when forms; that is, those that are not top level forms, or those in code processed byeval or compile. If the :execute situation is specified in such a form, then the body forms are processed as an implicit progn; otherwise, the eval-when _form_returns nil.

eval-whennormally appears as a top level form, but it is meaningful for it to appear as a non-top-level form. However, the compile-time side effects described in Section 3.2 Compilationonly take place when eval-when appears as a top level form.

Examples:

One example of the use of eval-when is that for the compiler to be able to read a file properly when it uses user-defined_reader macros_, it is necessary to write

(eval-when (:compile-toplevel :load-toplevel :execute) (set-macro-character #$ #'(lambda (stream char) (declare (ignore char)) (list 'dollar (read stream))))) T

This causes the call to set-macro-character to be executed in the compiler's execution environment, thereby modifying its reader syntax table.

;;; The EVAL-WHEN in this case is not at toplevel, so only the :EXECUTE ;;; keyword is considered. At compile time, this has no effect. ;;; At load time (if the LET is at toplevel), or at execution time ;;; (if the LET is embedded in some other form which does not execute ;;; until later) this sets (SYMBOL-FUNCTION 'FOO1) to a function which ;;; returns 1. (let ((x 1)) (eval-when (:execute :load-toplevel :compile-toplevel) (setf (symbol-function 'foo1) #'(lambda () x))))

;;; If this expression occurs at the toplevel of a file to be compiled, ;;; it has BOTH a compile time AND a load-time effect of setting ;;; (SYMBOL-FUNCTION 'FOO2) to a function which returns 2. (eval-when (:execute :load-toplevel :compile-toplevel) (let ((x 2)) (eval-when (:execute :load-toplevel :compile-toplevel) (setf (symbol-function 'foo2) #'(lambda () x)))))

;;; If this expression occurs at the toplevel of a file to be compiled, ;;; it has BOTH a compile time AND a load-time effect of setting the ;;; function cell of FOO3 to a function which returns 3. (eval-when (:execute :load-toplevel :compile-toplevel) (setf (symbol-function 'foo3) #'(lambda () 3)))

;;; #4: This always does nothing. It simply returns NIL. (eval-when (:compile-toplevel) (eval-when (:compile-toplevel) (print 'foo4)))

;;; If this form occurs at toplevel of a file to be compiled, FOO5 is ;;; printed at compile time. If this form occurs in a non-top-level ;;; position, nothing is printed at compile time. Regardless of context, ;;; nothing is ever printed at load time or execution time. (eval-when (:compile-toplevel) (eval-when (:execute) (print 'foo5)))

;;; If this form occurs at toplevel of a file to be compiled, FOO6 is ;;; printed at compile time. If this form occurs in a non-top-level ;;; position, nothing is printed at compile time. Regardless of context, ;;; nothing is ever printed at load time or execution time. (eval-when (:execute :load-toplevel) (eval-when (:compile-toplevel) (print 'foo6)))

See Also:

compile-file, Section 3.2 Compilation

Notes:

The following effects are logical consequences of the definition of eval-when:

which would be treated by the above rules the same as
(defun bar (x)
(setf (symbol-function 'foo) #'(lambda () (+ x 3))))
when the definition of bar is not a top level form.

Allegro CL Implementation Details:

None.