我有这个宏(来自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?
答案 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)