为什么必须在单独的表达式中评估'require'以使用该包

时间:2009-07-06 22:55:11

标签: lisp common-lisp

我有一些lisp初始化代码:

(eval-when (:compile-toplevel :load-toplevel :execute)
  (require 'asdf))

(eval-when (:compile-toplevel :load-toplevel :execute)
  (push #p"c\:\\lisp\\clsql-4.0.4\\" asdf:*central-registry*))

为什么这个版本会编译,而这个版本:

(eval-when (:compile-toplevel :load-toplevel :execute)
  (require 'asdf)
  (push #p"c\:\\lisp\\clsql-4.0.4\\" asdf:*central-registry*))

在第3行的编译文件中产生错误,asdf是一个无法识别的包?

我正在使用ccl,并且(require'asdf)被记录为引入ASDF的内置版本。

2 个答案:

答案 0 :(得分:9)

以下某些细节可能不准确,但大致如下:

Lisp“引擎”经历了四个阶段:读取时间,宏扩展时间,编译时间和运行时间。

首先完整阅读每个顶级表单。然而,阅读涉及各个符号的解析。由于在eval-when表单的读取时间内尚未加载ASDF,因此无法解析符号asdf:*central-registry*,这会产生上述读取错误。

答案 1 :(得分:4)

请参阅Svante的答案。

有时你可能想要解决这个问题。然后,您需要在RUNTIME的代码中查找符号。

(push somepath (symbol-value (find-symbol "*CENTRAL-REGISTRY*" "ASDF")))

可以使用上面的代码,因为符号asdf:* central-registry *不是直接使用,而是使用符号名称和包名称在运行时查找。