After reading a lot of documentation regarding Lisp eval-when
operator I still can't understand its uses, I know with this operator I can control the evaluation time of my expressions but I can't figure out any example where this may be applicable ?
Best Regards, utxeee.
Compilation of a Lisp file
Take for example the compilation of a Lisp file. The Lisp compiler processes the top-level forms. These can be arbitrary Lisp forms, DEFUNs, DEFMACROS, DEFCLASS, function calls,...
The whole story how the file compiler works is too complex to explain here, but a few things:
the file compiler generates code for a
(DEFUN foo () )
form. But it does not execute the defun form. Thus during compilation it is known that there is a functionFOO
, but the code of ˋFOOˋ is not available during the compilation. The compiler generates the code for the compiled file, but does not keep it in memory. You can't call such a function at compile time.for macros this works slightly different:
(DEFMACRO BAZ ...)
. The file compiler will not only compile the macro and note that it is there, but it will also make the macro available at compilation time. It is loaded into the compiler environment.Thus imagine the sequence of forms in a file:
This works because the file compiler knows the macro
BAZ
and when it compiles the code forFOO
, then it can expand the macro form.Now let's look at the following example:
Above will not work. Now the macro
BAZ
uses the functionBAR
by calling it. When the compiler tries to compile the functionFOO
, it can't expand theBAZ
macro, becauseBAR
can't be called, because the code ofBAR
is not loaded into the compile-time environment.There are two solutions to this:
BAR
earlier using a separate file.Example for
EVAL-WHEN
:Now the
EVAL-WHEN
instructs the file compiler to actually run the DEFUN form during compilation. The effect of this is: the file compiler now knows the definition ofBAR
at compile time. Thus it is available later, when the file compiler need to callBAR
during macro expansion of the usage ofBAZ
.One could use only
:compile-toplevel
, when the function would not be needed after the compilation of the file. If it is used later, then we need to make sure that it gets loaded.So
EVAL-WHEN
allows to specify if a particular piece of code should be runEVAL-WHEN
is not used that often in user code. If you use it, then you should ask yourself if you really need it.