Time of Evaluation
==================
Normally, the byte-compiler does not actually execute the forms in a
file it compiles. For example, if a file contains `(setq foo t)', the
act of compiling it will not actually set `foo' to `t'. This is true
even if the `setq' was a top-level form (i.e., not enclosed in a
`defun' or other form). Sometimes, though, you would like to have
certain top-level forms evaluated at compile-time. For example, the
compiler effectively evaluates `defmacro' forms at compile-time so that
later parts of the file can refer to the macros that are defined.
- Special Form: eval-when (situations...) forms...
This form controls when the body FORMS are evaluated. The
SITUATIONS list may contain any set of the symbols `compile',
`load', and `eval' (or their long-winded ANSI equivalents,
`:compile-toplevel', `:load-toplevel', and `:execute').
The `eval-when' form is handled differently depending on whether
or not it is being compiled as a top-level form. Specifically, it
gets special treatment if it is being compiled by a command such
as `byte-compile-file' which compiles files or buffers of code,
and it appears either literally at the top level of the file or
inside a top-level `progn'.
For compiled top-level `eval-when's, the body FORMS are executed
at compile-time if `compile' is in the SITUATIONS list, and the
FORMS are written out to the file (to be executed at load-time) if
`load' is in the SITUATIONS list.
For non-compiled-top-level forms, only the `eval' situation is
relevant. (This includes forms executed by the interpreter, forms
compiled with `byte-compile' rather than `byte-compile-file', and
non-top-level forms.) The `eval-when' acts like a `progn' if
`eval' is specified, and like `nil' (ignoring the body FORMS) if
not.
The rules become more subtle when `eval-when's are nested; consult
Steele (second edition) for the gruesome details (and some
gruesome examples).
Some simple examples:
;; Top-level forms in foo.el:
(eval-when (compile) (setq foo1 'bar))
(eval-when (load) (setq foo2 'bar))
(eval-when (compile load) (setq foo3 'bar))
(eval-when (eval) (setq foo4 'bar))
(eval-when (eval compile) (setq foo5 'bar))
(eval-when (eval load) (setq foo6 'bar))
(eval-when (eval compile load) (setq foo7 'bar))
When `foo.el' is compiled, these variables will be set during the
compilation itself:
foo1 foo3 foo5 foo7 ; `compile'
When `foo.elc' is loaded, these variables will be set:
foo2 foo3 foo6 foo7 ; `load'
And if `foo.el' is loaded uncompiled, these variables will be set:
foo4 foo5 foo6 foo7 ; `eval'
If these seven `eval-when's had been, say, inside a `defun', then
the first three would have been equivalent to `nil' and the last
four would have been equivalent to the corresponding `setq's.
Note that `(eval-when (load eval) ...)' is equivalent to `(progn
...)' in all contexts. The compiler treats certain top-level
forms, like `defmacro' (sort-of) and `require', as if they were
wrapped in `(eval-when (compile load eval) ...)'.
Emacs includes two special forms related to `eval-when'. One of
these, `eval-when-compile', is not quite equivalent to any `eval-when'
construct and is described below.
The other form, `(eval-and-compile ...)', is exactly equivalent to
`(eval-when (compile load eval) ...)' and so is not itself defined by
this package.
- Special Form: eval-when-compile forms...
The FORMS are evaluated at compile-time; at execution time, this
form acts like a quoted constant of the resulting value. Used at
top-level, `eval-when-compile' is just like `eval-when (compile
eval)'. In other contexts, `eval-when-compile' allows code to be
evaluated once at compile-time for efficiency or other reasons.
This form is similar to the `#.' syntax of true Common Lisp.
- Special Form: load-time-value form
The FORM is evaluated at load-time; at execution time, this form
acts like a quoted constant of the resulting value.
Early Common Lisp had a `#,' syntax that was similar to this, but
ANSI Common Lisp replaced it with `load-time-value' and gave it
more well-defined semantics.
In a compiled file, `load-time-value' arranges for FORM to be
evaluated when the `.elc' file is loaded and then used as if it
were a quoted constant. In code compiled by `byte-compile' rather
than `byte-compile-file', the effect is identical to
`eval-when-compile'. In uncompiled code, both `eval-when-compile'
and `load-time-value' act exactly like `progn'.
(defun report ()
(insert "This function was executed on: "
(current-time-string)
", compiled on: "
(eval-when-compile (current-time-string))
;; or '#.(current-time-string) in real Common Lisp
", and loaded on: "
(load-time-value (current-time-string))))
Byte-compiled, the above defun will result in the following code
(or its compiled equivalent, of course) in the `.elc' file:
(setq --temp-- (current-time-string))
(defun report ()
(insert "This function was executed on: "
(current-time-string)
", compiled on: "
'"Wed Jun 23 18:33:43 1993"
", and loaded on: "
--temp--))