gpt4 book ai didi

macros - 将列表传递给 Common Lisp 中的宏

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

我在将列表传递给宏时遇到问题,该列表将用于生成函数名称。例如,下面的代码会导致错误。

(defmacro gen (str-lst)
`(defun ,(intern (string-upcase (car str-lst))) () (print "foo")))

(gen '("foo" "bar"))

产生的错误是:

*** - DEFUN/DEFMACRO: QUOTE is a special operator and may not be redefined. The following restarts are available: ABORT :R1
Abort main loop

我应该如何修改我的代码,我的代码有什么问题?

让我更加困惑的是下面的代码,关于哪个答案存在 here , 工作正常。

(defmacro easy-one (str-lst)
`(mapc #'(lambda (str) (print str)) ,str-lst))
(easy-one '("foo" "bar"))

最佳答案

不要引用列表。宏不会计算它们的参数,因此您无需像对普通函数那样对它们进行引用来防止它们被计算。

(gen ("foo" "bar"))

当你引用它时,你就在执行

(get (quote ("foo" "bar")))

str-list 的值是列表(quote ("foo""bar")),所以(car str-list) 是符号 QUOTE。结果,宏扩展为

(defun quote () (print "foo"))

这就是为什么您会收到一个错误,提示您正在尝试重新定义内置的 QUOTE

第二个示例的不同之处在于,您只是将参数替换到扩展中,而不是在扩展代码中使用它的值。所以它扩展为

(mapc #'(lambda (str) (print str)) '("foo" "bar")))

这里的列表将在展开运行时使用,而不是在展开宏时使用。它需要在那里被引用,以防止它被评估为函数调用。

您应该使用 macroexpand 来查看您的宏在调试时是如何扩展的。

关于macros - 将列表传递给 Common Lisp 中的宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56692896/

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