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

Macro: cl-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 cl-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 cl-eval-whens, 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 cl-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 cl-eval-whens are nested;
consult Steele (second edition) for the gruesome details (and
some gruesome examples).

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 cl-eval-whens 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 setqs.

Note that (cl-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 (cl-eval-when
(compile load eval) …).

Emacs includes two special forms related to cl-eval-when.
See Eval During Compile in GNU Emacs Lisp Reference Manual.
One of these, eval-when-compile, is not quite equivalent to
any cl-eval-when construct and is described below.

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.

Macro: cl-load-time-valueform

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, cl-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 cl-load-time-value
act exactly like progn.