1

我有这个宏(来自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)严格来说, is not 10

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

4

1 回答 1

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)
于 2012-06-03T01:58:26.083 回答