Lisp 从plist宏体中提取并执行闭包/lambda

Lisp 从plist宏体中提取并执行闭包/lambda,lisp,common-lisp,lisp-macros,Lisp,Common Lisp,Lisp Macros,我正在尝试创建一个宏(条),它应该像这样使用: (let ((my-var "foo")) (bar ("some") :buzz (lambda () (format t "~a~%" my-var)))) 宏基本上应该只对所有lambda执行函数,并考虑MY-VAR 我想到的是: (defmacro bar ((thing) &body body) `(funcall (coerce (getf

我正在尝试创建一个宏(
),它应该像这样使用:

(let ((my-var "foo"))
   (bar ("some")
        :buzz (lambda () (format t "~a~%" my-var))))
宏基本上应该只对所有lambda执行函数,并考虑MY-VAR

我想到的是:

(defmacro bar ((thing) &body body)
   `(funcall (coerce (getf (list ,@body) :buzz) 'function)))
这行得通,它会打印“foo”。
但是我想知道这是怎么做到的,还是有更好的方法来做到这一点。

首先,如果不需要额外的、未使用的参数,那么这就是
funcall
,因为
(lambda…
表示函数

(let ((my-var "foo"))
  (funcall (lambda () (format t "~a~%" my-var))))
所以,即使你不想调用这个
funcall
,你也可以把它写成函数,而不是宏:它不做任何代码转换。但您可能确实需要这个额外的参数,并且您打算在扩展中使用它,因此您需要的是一个宏,它接受关键字参数并只扩展为合适的
funcall
形式:

(defmacro bar ((thing) &key (buzz '(lambda ())))
  (declare (ignore thing))
  `(funcall ,buzz))

首先,如果不需要额外的、未使用的参数,那么这就是
funcall
,因为
(lambda…
表示函数

(let ((my-var "foo"))
  (funcall (lambda () (format t "~a~%" my-var))))
所以,即使你不想调用这个
funcall
,你也可以把它写成函数,而不是宏:它不做任何代码转换。但您可能确实需要这个额外的参数,并且您打算在扩展中使用它,因此您需要的是一个宏,它接受关键字参数并只扩展为合适的
funcall
形式:

(defmacro bar ((thing) &key (buzz '(lambda ())))
  (declare (ignore thing))
  `(funcall ,buzz))

谢谢事实上,我需要这个未使用的论点。这只是一个简化的例子,从一个更大的周围设置。我实际上没有考虑关键的论点。但这意味着lambda参数在宏定义的lambda列表中,而不是在主体中。我需要考虑一下宏是否应该这样使用。@曼弗雷德:您可以同时使用:
(defmacro foo((thing)&body x&key…
)很好。这确实意味着主体被约束为关键字-值对(您可以使用
&允许其他键
说它可以是任何这样的对).正如你所说,我怀疑你需要考虑你的目标是什么语法(我经常遇到这个问题!)好的。在&body之后使用&key似乎可以正常工作。谢谢。我确实需要未使用的参数。这只是一个简化的例子,来自更大的环境设置。我实际上没有考虑&key参数。但这意味着lambda参数在宏定义的lambda列表中,而不是在body中。我需要考虑这是宏应该如何使用的。@曼弗雷德:您可以同时使用:
(defmacro foo((thing)和body x&key…
)很好。这确实意味着body被约束为关键字-值对(您可以使用
&允许其他键
说它可以是任何这样的对)。我怀疑正如你所说,你需要考虑你的目标语法(我经常遇到这个问题!)好的。这似乎可以按照我的意愿使用&key after&body。