gpt4 book ai didi

macros - 调用函数的宏在解释器中有效,在编译器中失败(SBCL + CMUCL)

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

a macro-related question I recently posted to SO 中的建议,我通过调用函数编写了一个名为“快速”的宏 (here is the standalone code in pastebin) :

(defun main ()
(progn
(format t "~A~%" (+ 1 2 (* 3 4) (+ 5 (- 8 6))))
(format t "~A~%" (fast (+ 1 2 (* 3 4) (+ 5 (- 8 6)))))))

这适用于 SBCL 和 CMUCL 下的 REPL:

$ sbcl
This is SBCL 1.0.52, an implementation of ANSI Common Lisp.
...
* (load "bug.cl")
22
22

$

不幸的是,代码不再编译:

$ sbcl
This is SBCL 1.0.52, an implementation of ANSI Common Lisp.
...
* (compile-file "bug.cl")
...
; during macroexpansion of (FAST (+ 1 2 ...)). Use *BREAK-ON-SIGNALS* to
; intercept:
;
; The function COMMON-LISP-USER::CLONE is undefined.

看来,通过在编译时让我的宏“快速”调用函数(“克隆”、“operation-p”),我在 Lisp 编译器中触发了问题(在 CMUCL 和 SBCL 中都得到了验证)。

关于我做错了什么和/或如何解决这个问题有什么想法吗?

最佳答案

关于您的代码的一些评论。

  • 一个对象的多次相等性测试可以用MEMBER

    代替
  • 后跟逗号的反引号没有任何作用。您可以将其删除。

  • 您可以通过以下方式确保您的函数可用于宏:a) 将这些函数移动到附加文件并在使用宏之前编译/加载该文件,b) 使用 EVAL-WHEN通知编译器评估函数的定义或通过 c) 将函数作为局部函数添加到宏中

例子:

(defmacro fast (&rest sexpr)
(labels ((operation-p (x)
(member x '(+ - * /)))
(clone (sexpr)
(if (consp sexpr)
(destructuring-bind (head . tail) sexpr
(if (operation-p head)
`(the fixnum (,head ,@(clone tail)))
(cons (clone head) (clone tail))))
sexpr)))
(car (clone sexpr))))

请注意,这和您的 FAST 版本都不是完整的代码遍历器。它们只识别简单的函数调用(而不识别其他 Lisp 结构,如 LAMBDA、LET、FLET、LABELS 等)。

关于macros - 调用函数的宏在解释器中有效,在编译器中失败(SBCL + CMUCL),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8138714/

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