【发布时间】:2024-01-15 16:25:01
【问题描述】:
为了练习,我已经定义了
(defmacro quote-paren
"body -> `(body)"
[& body]
`(~@body))
具有预期的转换(quote-paren body) => ``(body)`。它似乎满足了一些基本测试:
user=> (macroexpand-1 `(quote-paren 3 4 5))
(3 4 5)
user=> (macroexpand-1 `(quote-paren println "hi"))
(clojure.core/println "hi")
user=> (macroexpand-1 `(quote-paren (println "hi")))
((clojure.core/println "hi"))
不过,我一直在用这个 do-while 宏(修改自 here)对其进行测试:
(defmacro do-while
[test & body]
(quote-paren loop []
~@body
(when ~test
(recur))))
(def y 4)
(do-while (> y 0)
(def y (dec y)))
但结果是
IllegalStateException Attempting to call unbound fn: #'clojure.core/unquote-splicing clojure.lang.Var$Unbound.throwArity (Var.java:43)
我不明白这一点,因为从我可以看到 `quote-paren' 宏工作正常(插入了 ~@body):
user=> (macroexpand-1
`(quote-paren loop []
(def y (dec y))
(when ~test
(recur))))
(clojure.core/loop [] (def user/y (clojure.core/dec user/y)) (clojure.core/when #<core$test clojure.core$test@1f07f672> (recur)))
但尝试宏扩展 do-while 会导致“unbound fn”。有什么我遗漏的微妙之处吗?
【问题讨论】:
标签: clojure macros quote parentheses