EVAL-WHEN(3cl)

Common Lisp Reference

EVAL-WHEN(3cl)

 

NAME

eval-when – evaluate forms, but only in specified situations (special operator)

SYNOPSIS


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

ARGUMENTS and VALUES

situation—One of the symbols :compile-toplevel, :load-toplevel, :execute, compile, load, or eval. 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.

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 by eval 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-when normally appears as a top level form, but it is meaningful for it to appear as a non-top-level form. However, certain compile-time side effects only take place when eval-when appears as a top level form.

AFFECTED BY

(none)

EXCEPTIONAL SITUATIONS

(none)

NOTES

The function compile-file performs compilation of forms in a file, and produces an output file that can be loaded by using load. Normally, the top level forms appearing in a file compiled with compile-file are evaluated only when the resulting compiled file is loaded, and not when the file is compiled. However, it is typically the case that some forms in the file need to be evaluated at compile time so the remainder of the file can be read and compiled correctly.

The eval-when special form can be used to control whether a top level form is evaluated at compile time, load time, or both. It is possible to specify any of three situations with eval-when.

The behavior of this form can be more precisely understood in terms of a model of how compile-file processes forms in a file to be compiled. There are two processing modes, called “not-compile-time” (NCT) and “compile-time-too” (CTT).

Successive forms are read from the file by compile-file and processed in NCT mode; in this mode, compile-file arranges for forms to be evaluated only at load time and not at compile time. When compile-file is in CTT mode, forms are evaluated both at compile time and load time.

When compiling a top-level eval-when:

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

EXAMPLES

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

  2. The EVAL-WHEN in this case is not at top level, 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))))  

  3. If this expression occurs at the top level 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)))))    

  4. If this expression occurs at the top level 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)))    

  5. This always does nothing. It simply returns NIL.
       (eval-when (:compile-toplevel)
           
    (eval-when (:compile-toplevel)
               
    (print foo4)))     

  6. If this form occurs at top level 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)))    

  7. If this form occurs at top level 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(3cl)

AUTHOR and COPYRIGHT

Substantial portions of this page are taken from draft proposed American National Standard for Information Systems—Programming Language—Common Lisp, X3J13/94-101R, Version 15.17R, Fri 12-Aug-1994 6:35pm EDT; no copyright indicated.

Additional clarification and comments by Michael Marking <marking@tatanka.com>, http://www.tatanka.com/software/cl-manpages/; alternatively, https://github.com/wakinyantanka/cl-manpages/. Copyright 2017 Michael Marking as both an original and a derivative work.

Licensed under Creative Commons Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0).

This page last revised Sunday 26 February 2017.