我无法理解macroexpand和macroexpand-1之间的区别。

你能提供例子吗?

最佳答案

假设我们有以下代码:

(defmacro inner-macro [arg]
  `(println ~arg))

(defmacro top-level-macro [arg]
  `(inner-macro ~arg))

(defn not-a-macro [] nil)

然后,macroexpand-1的文档说:



实际上,它确实:
user> (macroexpand-1 '(inner-macro "hello"))
(clojure.core/println "hello")

user> (macroexpand-1 '(top-level-macro "hello"))
(user/inner-macro "hello")

user> (macroexpand-1 '(not-a-macro))
(not-a-macro)

换句话说,如果提供的形式是宏形式,则macroexpand-1仅执行宏扩展的一个步骤。

然后,macroexpand的文档:



例子:
user> (macroexpand '(top-level-macro "hello"))
(clojure.core/println "hello")

发生了什么?一旦(top-level-macro "hello")扩展为宏形式的(user/inner-macro "hello")macroexpand将再次执行扩展。第二次扩展的结果是(clojure.core/println "hello")。它不是宏形式,因此macroexpand仅返回它。

因此,只是改写文档,macroexpand将递归进行扩展,直到顶级形式不是宏形式。

此外,macroexpand的文档中还有其他说明:



这意味着什么?假设我们还有一个宏:
(defmacro subform-macro [arg]
  `(do
     (inner-macro ~arg)))

让我们尝试扩展它:
user> (macroexpand-1 '(subform-macro "hello"))
(do (user/inner-macro "hello"))

user> (macroexpand '(subform-macro "hello"))
(do (user/inner-macro "hello"))

由于(do ...)形式不是宏macroexpand-1,因此macroexpand仅返回它,仅此而已。不要指望macroexpand将执行以下操作:
user> (macroexpand '(subform-macro "hello"))
(do (clojure.core/println "hello"))

关于clojure - Clojure中的macroexpand和macroexpand-1有什么区别,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37048167/

10-09 22:14