Why did EVAL-WHEN with :LOAD-TOPLEVEL not run the body when I LOAD the file?

Viewed 72

I have written this Lisp program:

(eval-when (:load-toplevel)
  (princ "Hello!"))

However, when I load the program, the body of the eval-when is not run.

$ sbcl
* (load "hello.lisp")
T
*

What is happening? In the eval-when, I used :load-toplevel to specify that its body should be run when I load the file. I am surprised that (princ "Hello!") did not run when I loaded the file.

2 Answers

From CLHS:

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.

Since you're not loading the compiled file, the :load-toplevel situation doesn't apply. Use :execute to execute code when the source is being loaded.

Refer to the answer by user "Barmar" for the HyperSpec reference.

When the file is compiled using compile-file, :load-toplevel instructs the compiler to arrange for the body of the eval-when to be run when the compiled program is loaded.

Therefore, to run the body of the eval-when in the OP's example, first compile the file, then load the fasl file that is produced:

$ sbcl
* (compile-file "hello.lisp")
; compiling file "/home/user/programs/hello.lisp" (written 16 APR 2022 12:34:56 PM):

; wrote /home/user/programs/hello.fasl
; compilation finished in 0:00:00.003
#P"/home/user/programs/hello.fasl"
NIL
NIL
* (load "hello.fasl")
Hello!
T
* 
Related