Common Lisp 宏中的闭包
Closure inside a Common Lisp Macro
在下面的代码中,我如何使用 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)))))
当展开这样的调用时:
(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)))
其中带有 W
和 H
引用的原始表达式丢失了。我尝试反引用 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-form
的 x 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 对如何改进代码的解释。
在下面的代码中,我如何使用 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)))))
当展开这样的调用时:
(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)))
其中带有 W
和 H
引用的原始表达式丢失了。我尝试反引用 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-form
的 x 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 对如何改进代码的解释。