Macros 从Quicklisp包中的宏调用函数

Macros 从Quicklisp包中的宏调用函数,macros,lisp,common-lisp,quicklisp,Macros,Lisp,Common Lisp,Quicklisp,我把它放在asd上 和package.lisp 进入~/quicklisp/本地项目/失败。使用安装了Quicklisp的Clozure CL,我运行 (ql:quickload :failing) 这让我 To load "failing": Load 1 ASDF system: failing ; Loading "failing" [package failing] > Error: Undefined function FOO called with argumen

我把它放在asd上

和package.lisp

进入~/quicklisp/本地项目/失败。使用安装了Quicklisp的Clozure CL,我运行

(ql:quickload :failing)
这让我

To load "failing":
  Load 1 ASDF system:
    failing
; Loading "failing"
[package failing]
> Error: Undefined function FOO called with arguments () .
> While executing: BAR, in process listener(1).
> Type :GO to continue, :POP to abort, :R for a list of available restarts.
> If continued: Retry applying FOO to NIL.
> Type :? for other options.

似乎我无法从包中的宏调用函数。为什么不呢?

只有在加载之前编译文件时才会发生这种情况。通常,它与ASDF无关,ASDF是一种用于管理文件依赖关系和编译/加载属于名称空间且与ASDF无关的代码或包的工具

它与文件编译在Common Lisp中的工作方式有关:

文件编译器看到函数foo并对其进行编译->将其代码写入文件。它没有!将代码加载到编译时环境中

然后,文件编译器会看到宏栏并对其进行编译->将代码写入文件。是的!将代码加载到编译时环境中

然后,文件编译器会看到宏表单栏并希望将其展开。它调用宏功能栏。它调用foo,这是未定义的,因为它不在编译时环境中

解决方案:

将函数定义放在ASDF系统中的单独文件中,并提前编译/加载它

将函数作为本地函数放入宏中

将EVAL-WHEN:COMPILE-TOPLEVEL:LOAD-TOPLEVEL:EXECUTE。。。围绕函数定义。它使定义在编译时执行


记住:文件编译器需要知道宏函数->否则它将无法宏扩展代码。普通函数只是在编译文件时被编译,而不是在编译时加载。

谢谢,解决了我的问题。作为一个附带问题,为什么在CommonLisp中包如此复杂?直观地说,我可以想象,当我想要编写模块化代码时,我只是将其拆分成文件,然后导入正确的文件。例如,Python中就是这样发生的。在Common Lisp的DNA中有什么东西使得这不可能吗?@slimetree:我们正在讨论宏和文件编译的组合。香草python并没有提供这一点。
(ql:quickload :failing)
To load "failing":
  Load 1 ASDF system:
    failing
; Loading "failing"
[package failing]
> Error: Undefined function FOO called with arguments () .
> While executing: BAR, in process listener(1).
> Type :GO to continue, :POP to abort, :R for a list of available restarts.
> If continued: Retry applying FOO to NIL.
> Type :? for other options.