`(body)" [& body] `(~@body)) 其中具有预期的转换 (quote-paren-6ren">
gpt4 book ai didi

clojure - clojure quote-paren `( ... ) 宏的问题

转载 作者:行者123 更新时间:2023-12-04 12:42:13 24 4
gpt4 key购买 nike

为了实践,我已经定义了

(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”。我错过了一些微妙的东西吗?

最佳答案

缺少 quote-paren 之前的语法引用

user> (defmacro do-while
[test & body]
`(quote-paren loop []
~@body
(when ~test
(recur))))
#'user/do-while

然后正确扩展:
user> (macroexpand '(do-while (> y 0)
(def y (dec y))))
(loop* [] (def y (dec y)) (clojure.core/when (> y 0) (recur)))

并且似乎有效:
user> (def y 4)
#'user/y
user> (do-while (> y 0)
(def y (dec y)))
nil
user>

关于clojure - clojure quote-paren `( ... ) 宏的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12805800/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com