从Quicklisp包中的宏调用函数 [英] Calling function from macro inside Quicklisp package
问题描述
我放入了 failing.asd
(in-package :asdf-user)
(defsystem "failing"
:description "some code destined to fail"
:version "0.1"
:author "me"
:components ((:file "package")))
和 package.lisp
(defpackage :failing
(:export :foo :bar))
(in-package :failing)
(defun foo () 42)
(defmacro bar ()
(let ((x (foo)))
`(print ,x)))
(bar)
进入〜/quicklisp/local-projects/failing .使用安装了Quicklisp的Clozure CL,我运行
into ~/quicklisp/local-projects/failing. Using Clozure CL with Quicklisp installed, I run
(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.
似乎我无法从包内的宏调用函数.为什么不呢?
It seems I can't call a function from a macro inside the package. Why not?
推荐答案
只有在加载文件之前对其进行编译时,才会发生这种情况.通常,它与ASDF(用于管理文件依赖性和编译/加载代码的工具)或程序包(它们是名称空间,与ASDF无关)无关.
That can only happen when the file gets compiled before loaded. Generally it has nothing to do with ASDF (which is a tool to manage file dependencies and to compile/load code) or packages (which are namespaces and are not in any way related to ASDF).
与Common Lisp中文件编译的工作方式有关:
文件编译器看到函数foo
并对其进行编译->将其代码写入文件. 它不会(!)将代码加载到编译时环境中.
The file compiler sees the function foo
and compiles it -> the code for it gets written to a file. It does not (!) load the code into the compile-time environment.
文件编译器然后看到宏栏并进行编译->代码被写入文件. 确实(!)将代码加载到编译时环境中.
The file compiler then sees the macro bar and compiles it -> the code gets written to a file. It does (!) load the code into the compile-time environment.
文件编译器随后会看到宏格式(bar)
,并希望对其进行扩展.它调用宏函数bar
.哪个会调用foo
,它是未定义的,因为它不在编译时环境中.
The file compiler then sees the macro form (bar)
and wants to expand it. It calls the macro function bar
. Which calls foo
, which is undefined, since it is not in the compile-time environment.
解决方案:
-
将功能定义放入ASDF系统中的单独文件中,并尽早进行编译/加载.
put the function definition in a separate file in the ASDF system and compile/load it earlier.
将宏内部的函数作为局部函数
put the function inside the macro as a local function
将(EVAL-WHEN (:COMPILE-TOPLEVEL :LOAD-TOPLEVEL :EXECUTE) ...)
放在函数定义周围.它使定义在编译时执行.
put (EVAL-WHEN (:COMPILE-TOPLEVEL :LOAD-TOPLEVEL :EXECUTE) ...)
around the function definition. It causes the definition to be executed at compile-time.
记住:文件编译器需要了解宏函数->否则,将无法对代码进行宏扩展.普通功能只是在文件的编译过程中被编译而未在编译时加载.
Remember: the file compiler needs to know macro functions -> otherwise it would not be able to macroexpand code. Ordinary functions just get compiled, but not loaded at compile time, during compilation of a file.
这篇关于从Quicklisp包中的宏调用函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!