当 defconstant 使用同一文件中的函数时无法编译文件

Unable to compile file when a defconstant uses a function from the same file

这是example.lisp:

(defun f (x)
  (* x 2))

(defconstant +n+ (f 1))

当我尝试使用 (compile-file "example.lisp") 编译文件时,我在编译常量时出错:The function COMMON-LISP-USER::F is undefined。怎么会这样?在使用它定义常量之前,我已经定义了函数 f 。如何定义一个常量,其值为函数的 return 值?

我正在使用 SBCL 2.0.1。

来自 DEFCONSTANT:

[...] users must ensure that the initial-value can be evaluated at compile time (regardless of whether or not references to name appear in the file) and that it always evaluates to the same value.

但是 COMPILE-FILE and 3.2.3 File Compilation 只需要 DEFUN 形式来确定 F 存在,而不是可以在编译期间评估。

您需要 LOAD 定义的结果文件才能在您的环境中可用(例如,Slime 编译文件 加载结果)。同样,当您在 REPL 中一次评估一个表单时,定义立即可用,就好像完成了一个小的编译加载周期一样。

您有两个主要选择:

  • defun 包装成 eval-when 形式

      (eval-when (:compile-toplevel :load-toplevel :execute)
        (defun f (x) (* x 2)))
    
  • 将两种形式放在不同的文件中,并让第二种形式在系统中(在 defsystem 意义上)依赖于第一种形式:

      (defsystem "foo"
        :components ((:file "define-f")
                     (:file "define-constant"))
        :serial t)