Para la práctica, he definidoProblemas con clojure Cotización en paren `(...) macro
(defmacro quote-paren
"body -> `(body)"
[& body]
`([email protected]))
que tiene la transformación esperada (quote-paren body)
=>` `(cuerpo)`. Se parece satisfacer algunas pruebas básicas:
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"))
Sin embargo, he estado probando con este do-while macro (modificado de 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)))
pero el resultado es
IllegalStateException Attempting to call unbound fn: #'clojure.core/unquote-splicing clojure.lang.Var$Unbound.throwArity (Var.java:43)
No entiendo esto, porque por lo que puedo ver, la macro `quote-paren 'funciona bien (con ~ @ cuerpo enchufado):
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)))
Pero al intentar macroexpandir do-while
provoca un "unbound fn
". ¿Hay algo sutil que me estoy perdiendo?
y así como un comentario al margen: el uso de (def y ...) para control de bucle puede tener consecuencias involuntarias que no están relacionadas con esta pregunta ;-) –
Hmm, tienes razón, pero ese tipo de derrotas el propósito de mi ejercicio. ¿Hay alguna forma de hacer una cita-paren que reemplace '(quote-paren stuff)' con ''(stuff)'? En resumen, no es necesario escribir 'en la definición de macro. – spacingissue
He intentado reemplazar '(quote-paren stuff)' con '(quote (cosas))' pero parece dejar de reconocer las variables; es decir '(defmacro do-while [prueba y cuerpo] (cita (circular [] ~ @ cuerpo (cuando ~ prueba (reaparecer)))))' y funcionando resultados en 'java.lang CompilerException. RuntimeException: no se puede resolver el símbolo: body en este contexto, compilando: (NO_SOURCE_PATH: 58) 'Pero si esto se aborda mejor en otra pregunta, lo entendería. – spacingissue