为什么宏扩展不会扩展Clojure中的嵌套表单?

时间:2017-09-02 21:45:04

标签: clojure macros

我不明白如何获得完整的宏扩展。

使用此代码

(when true (when true true))

我想获得完整的宏扩展

(if true (do (if true (do true)))

但我不能

我理解macroexpansion-1将解决第一级扩展问题:

(macroexpand-1 '(when true (when true true)))

(if true (do (when true true)))

但是为什么当我再次打电话macroexpand-1时(那应该做macroexpand):

(macroexpand-1 '(if true (do (when true true))))

我得到了完全相同的结果?

(if true (do (when true true)))

我期待完整的宏扩张。

宏扩展仅适用于顶级表单吗?

我知道expand-all命名空间中的clojure.walk函数,所以我 假设macroexpand不适用于嵌套结构。我对吗 ?

1 个答案:

答案 0 :(得分:6)

你是对的。

另见https://clojuredocs.org/clojure.core/macroexpand

它声明:

  

请注意,macroexpand-1和macroexpand都不会在子表单中展开宏。

而且macroexpand-all确实进行了递归扩展:

> (clojure.walk/macroexpand-all '(when true (when true true))) 
(if true (do (if true (do true))))

另见https://clojuredocs.org/clojure.walk/macroexpand-all

其中声明:

  

以形式递归执行所有可能的宏扩展。

你的例子

(macroexpand-1 '(if true (do (when true true))))

可能会让您感到困惑,但它会像文档所说的那样:

  

(macroexpand-1 form)如果form表示一个宏表单,则返回它   扩展,否则返回形式。

所以,因为'如果'不是宏,它只是返回,而不进入子表单...