Common Lisp 宏中的闭包

Closure inside a Common Lisp Macro

在下面的代码中,我如何使用 xy 变量来反映在宏调用时给出的表达式?

(defmacro defrule (init-form &rest replication-patterns)
  (let (rule-table)
   `(destructuring-bind (p x y) ',init-form
       #'(lambda (w h) (list x y)))))

当展开这样的调用时:

(defrule (70 (* 1/2 w) (+ h 3)))

它returns:

(DESTRUCTURING-BIND (P X Y) '(70 (* 1/2 W) (+ H 3))
  #'(LAMBDA (W H) (LIST X Y)))

其中带有 WH 引用的原始表达式丢失了。我尝试反引用 lambda 函数创建:

(defmacro defrule (init-form &rest replication-patterns)
  (let (rule-table)
    `(destructuring-bind (p x y) ',init-form
       `#'(lambda (w h) (list ,x ,y)))))

但同一个电话:

(defrule (70 (* 1/2 w) (+ h 3)))

扩展为:

(DESTRUCTURING-BIND
    (P X Y)
    '(70 (* 1/2 W) (+ H 3))
  `#'(LAMBDA (W H) (LIST ,X ,Y)))

return缺点:

#'(LAMBDA (W H) (LIST (* 1/2 W) (+ H 3)))

不能被 funcall 使用,并且可以像函数对象一样轻松传递。我如何 return 一个带有表达式的函数对象作为 init-formx y 部分的参数传入,并且闭包函数可以看到可能的 W H 引用?

你有缺点,因为你嵌套了反引号。

你不需要在 destructuring-bind 周围加反引号,因为你在宏展开时解构,你可以直接在宏 lambda 列表中进行解构。

(defmacro defrule ((p x y) &rest replication-patterns)
  (let (rule-table)
    `#'(lambda (w h) (list ,x ,y))))

查看您的代码:

(defmacro defrule (init-form &rest replication-patterns)
  (let (rule-table)
   `(destructuring-bind (p x y) ',init-form
       #'(lambda (w h) (list x y)))))

您想要一个扩展为代码的宏,然后在运行时获取代码并returns一个闭包?

这可能不是个好主意。

记住:它是宏,它应该在宏展开时操作代码。在运行时,代码应该是固定的。请参阅 Barmar 对如何改进代码的解释。