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

Dem*_*jon 2 macros clojure

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

有了这段代码

(when true (when true true))
Run Code Online (Sandbox Code Playgroud)

我想得到完整的宏扩展

(if true (do (if true (do true)))
Run Code Online (Sandbox Code Playgroud)

但我不能

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

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

(if true (do (when true true)))
Run Code Online (Sandbox Code Playgroud)

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

(macroexpand-1 '(if true (do (when true true))))
Run Code Online (Sandbox Code Playgroud)

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

(if true (do (when true true)))
Run Code Online (Sandbox Code Playgroud)

我期待完整的宏观扩张.

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

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

Pet*_*ter 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))))
Run Code Online (Sandbox Code Playgroud)

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

它声明:

递归地执行表单中所有可能的宏扩展.

你的榜样

(macroexpand-1 '(if true (do (when true true))))
Run Code Online (Sandbox Code Playgroud)

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

(macroexpand-1 form)如果form表示一个宏表单,则返回其扩展,否则返回表单.

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