对于宏扩展,等式断言失败了

时间:2012-06-03 01:50:46

标签: macros clojure

我有这个宏(来自clojure-koans)应该允许使用中缀运算符:

(defmacro infix-better [form]
  `(~(second form)
    (first form)
    (last form) ))

它做了它应该做的事情,但并没有完全扩展到同一个表达式。例如:

user=> (= '(* 10 2) (macroexpand '(infix-better (10 * 2))))
false
user=> '(* 10 2)                                           
(* 10 2)
user=> (macroexpand '(infix-better (10 * 2))) 
(* (clojure.core/first user/form) (clojure.core/last user/form))

当评估内部表达式时,最后一个输出最终会变为(* 10 2),但是相等测试返回false,因为(clojure.core/first user/form)严格来说不是10

如何让扩展的宏等同于等效的硬编码Clojure?

1 个答案:

答案 0 :(得分:2)

你必须取消引用第二个和第三个表单,就像你用第一个表单一样,~ - “当评估内部表达式时,最后一个输出最终会成为(* 10 2)”任何方式都是正确的 - 内在表达已经通过了评估的机会。

(defmacro infix-better [form]
  `(~(second form)
    ~(first form)
    ~(last form)))

修复它并保持代码结构相同,但真正的解构会给你带来更好的结果:

(defmacro infix-better [[x op y]]
  (list op x y)) ;; or `(~op ~x ~y)