En Clojure, necesita usar gensym
para crear símbolos para uso interno en sus macros para mantenerlos higiénicos. Sin embargo, a veces necesita usar el mismo símbolo en las comillas de sintaxis anidadas. Por ejemplo, si quiero enlazar un valor de un símbolo con let
e imprimirlo tres veces en un bucle desenrollado, lo haríaCoordinar auto-gensym en sintaxis-citas anidadas en Clojure
`(let [x# 1]
[email protected](repeat 3
`(println x#)))
Pero que produciría
(clojure.core/let [x__2__auto__ 1]
(clojure.core/println x__1__auto__)
(clojure.core/println x__1__auto__)
(clojure.core/println x__1__auto__))
x#
genera una símbolo diferente en el formulario let
que en los formularios println
anidados en él, porque se crearon a partir de diferentes citas de sintaxis.
para resolverlo, puedo generar el símbolo de antemano y lo inyecta a la sintaxis de las frases:
(let [x (gensym)]
`(let [~x 1]
[email protected](repeat 3
`(println ~x)))
)
Esto producirá el resultado correcto, con el mismo símbolo en todas partes es necesario:
(clojure.core/let [G__7 1]
(clojure.core/println G__7)
(clojure.core/println G__7)
(clojure.core/println G__7))
Ahora, si bien produce el resultado correcto, el código en sí parece feo y detallado. No me gusta tener que "declarar" un símbolo, y la sintaxis de inyección hace que parezca que proviene de fuera de la macro, o que se calcula en algún lugar dentro de ella. Quiero poder usar la sintaxis auto-gensym, lo que deja en claro que esos son símbolos macro internos.
Entonces, ¿hay alguna forma de usar auto-gensym con las comillas de sintaxis anidadas y hacer que produzcan el mismo símbolo?
Gracias. No me puedo poner normal, citando la expresión de impresión para que funcione, pero supongo que será engorroso para macros más complejos de todos modos ... –
Si haces algo así, te recomiendo usar \ 'println, not 'println - el primero no está sujeto a la captura de nombre en caso de que el macro usuario tenga un espacio de nombre inusual o un contexto léxico. – amalloy
¡buen punto! Voy a editar para arreglar ese –