为什么 EVAL-WHEN with :LOAD-TOPLEVEL 不是 运行 当我加载文件时的主体?

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

我写了这个 Lisp 程序:

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

但是,当我加载程序时,eval-when 的主体不是 运行。

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

这是怎么回事?在 eval-when 中,我使用 :load-toplevel 指定加载文件时其主体应为 运行。我很惊讶 (princ "Hello!") 在我加载文件时没有 运行。

来自 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.

由于您没有加载编译文件,:load-toplevel 情况不适用。使用 :execute 在加载源代码时执行代码。

HyperSpec 参考用户“Barmar”的回答。

当使用 compile-file 编译文件时,:load-toplevel 指示编译器将 eval-when 的主体安排为 运行,当编译程序为 loaded.

因此,对于OP示例中eval-when的运行主体,首先编译文件,然后加载生成的fasl文件:

$ 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
*