Macros 公共Lisp宏中的闭包

Macros 公共Lisp宏中的闭包,macros,common-lisp,Macros,Common Lisp,在下面的代码中,如何使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))) 它返回: (DESTRUC

在下面的代码中,如何使
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)))
它返回:

(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)))
返回一个CONS:

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

它不能被
funcall
使用,并且很容易像函数对象一样传递。如何返回带有表达式的函数对象,这些表达式是作为
init表单的
xy
部分的参数传入的,并且闭包函数可以看到
W H
引用?

因为嵌套了反引号,所以得到了一个cons

您不需要在
解构绑定
前后加上反引号,因为您是在宏展开时解构的,您可以直接在宏lambda列表中进行解构

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

你得到了一个缺点,因为你有反引号嵌套

您不需要在
解构绑定
前后加上反引号,因为您是在宏展开时解构的,您可以直接在宏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)))))
您需要一个宏,它可以展开为代码,然后在运行时接受代码并返回闭包

那可能不是个好主意

请记住:它是宏,应该在宏扩展时操作代码。在运行时,代码应该是固定的。请参阅Barmar关于如何改进代码的说明。

查看您的代码:

(defmacro defrule (init-form &rest replication-patterns)
  (let (rule-table)
   `(destructuring-bind (p x y) ',init-form
       #'(lambda (w h) (list x y)))))
您需要一个宏,它可以展开为代码,然后在运行时接受代码并返回闭包

那可能不是个好主意


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

这似乎是一个糟糕的设计,要求用户知道变量
W
H
是在扩展中生成的。这是程序内部结构的一部分,不打算由用户使用。在调用这个宏时,
W H
变量是未知的,所以我想返回一个函数,以后当它们可用时,可以用definite
W H
调用它。这看起来像是糟糕的设计,要求用户知道变量
W
H
是在扩展中生成的。这是程序内部结构的一部分,不供用户使用。在调用该宏时,
W H
变量是未知的,因此我想返回一个函数,该函数在以后可用时可以使用definite
W H
调用。