Clojure宏展开

8
为什么会这样?
(macroexpand '(.. arm getHand getFinger))

扩展到
(. (. arm getHand) getFinger)

当...时
(macroexpand '(-> arm getHand getFinger))

扩展为

(getFinger (clojure.core/-> arm getHand))

换句话说,为什么在第二个例子中->没有完全展开?
1个回答

10

macroexpand 只会将该表达式展开到函数位置的符号不再是一个宏时为止。你在 -> 的情况下注意到这一点的原因是 -> 宏是递归的。

在您的情况下,您需要使用 clojure.walk 中的 macroexpand-all 表达式。


这其实就是我问的原因。macroexpand 不应该一直展开 -> 直到它不再是一个宏吗?我看了一下 -> 的源代码,它最终似乎会解析为 "([x form] (if (seq? form) (with-meta `(~(first form) ~x ~@(next form)) (meta form)) (list form x)))"。也许我没有正确理解它。 - Ralph
1
@Ralph:macroexpand 不会展开子表单中的宏,因此 (-> arm getHand getFinger) 展开为 (clojure.core/-> (clojure.core/-> arm getHand) getFinger),这是因为 -> 是一个宏,所以展开为 (getFinger (clojure.core/-> arm getHand))。展开在此处停止,因为 getFinger 不是一个宏。 - Brian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接