Für die Praxis habe ichÄrger mit clojure Zitat-paren `(...) Makro
(defmacro quote-paren
"body -> `(body)"
[& body]
`([email protected]))
definiert, die die erwartete Transformation hat (quote-paren body)
=>` `(Körper)`. Es scheint, ein paar grundlegende Tests zu erfüllen:
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"))
Allerdings habe ich es getestet mit dieser do-while-Makro (modifiziert nach here):
(defmacro do-while
[test & body]
(quote-paren loop []
[email protected]
(when ~test
(recur))))
(def y 4)
(do-while (> y 0)
(def y (dec y)))
Aber das Ergebnis ist
IllegalStateException Attempting to call unbound fn: #'clojure.core/unquote-splicing clojure.lang.Var$Unbound.throwArity (Var.java:43)
Ich verstehe das nicht, denn von dem, was ich sehen kann, funktioniert das `quote-paren'-Makro gut (mit ~ @ Körper eingesteckt):
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 [email protected]> (recur)))
Aber versucht zu macroexpand do-while
verursacht eine "unbound fn
". Gibt es etwas Feines, das ich vermisse?
und nur als Neben Kommentar: mit (def y ...) for loop control kann unbeabsichtigte Folgen haben, die nichts mit dieser Frage zu tun haben ;-) –
Hmm, du hast Recht, aber das ist der Zweck meiner Übung. Gibt es überhaupt einen Zitat-Paren, der "(quote-paren stuff)" durch "(stuff)" ersetzt? Kurz gesagt, es ist unnötig, in der Makrodefinition zu schreiben. – spacingissue
Ich habe versucht, '(quote-paren stuff)' durch '(quote (stuff))' zu ersetzen, aber es scheint aufgehört zu haben, die Variablen zu erkennen; das heißt '(defmacro do-while [Test & body] (Zitat (loop [] ~ @ Körper (bei ~ Test (wiederholen)))))' und Ergebnisse in 'CompilerException java.lang läuft. RuntimeException: Das Symbol symbol: body konnte in diesem Kontext nicht aufgelöst werden. Kompilieren: (NO_SOURCE_PATH: 58) 'Wenn dies in einer anderen Frage am besten angesprochen wird, würde ich es verstehen. – spacingissue