gpt4 book ai didi

macros - 从 Quicklisp 包内的宏调用函数

转载 作者:太空宇宙 更新时间:2023-11-03 18:38:10 24 4
gpt4 key购买 nike

我把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,我运行

(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 没有任何关系)无关。

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

文件编译器 看到函数 foo 并编译它 -> 它的代码被写入文件。 它不会(!)将代码加载到编译时环境中。

文件编译器 然后看到宏 bar 并编译它 -> 代码被写入文件。 它确实(!)将代码加载到编译时环境中。

文件编译器 然后看到宏形式 (bar) 并想要扩展它。它调用宏函数bar。它调用未定义的 foo,因为它不在编译时环境中。

解决方案:

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

  • 将函数作为局部函数放在宏中

  • 在函数定义周围放置 (EVAL-WHEN (:COMPILE-TOPLEVEL :LOAD-TOPLEVEL :EXECUTE) ...)。它导致定义在编译时执行。

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

关于macros - 从 Quicklisp 包内的宏调用函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29442098/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com