es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

La expansión de macros de doseq en Babashka vs en Clojure.

En Babashka v0.6.2, puedo llamar a macroexpand en la macro for y la salida es algo como esto:

user=> (macroexpand '(for [i (range 10)] i))
(clojure.core/let [iter__1755__auto__ (clojure.core/fn iter__147 [s__148] (clojure.core/lazy-seq (loop [s__148 s__148] (clojure.core/let [s__148 (clojure.core/seq s__148)] (clojure.core/when s__148 (if (clojure.core/chunked-seq? s__148) (clojure.core/let [c__1753__auto__ (clojure.core/chunk-first s__148) size__1754__auto__ (clojure.core/int (clojure.core/count c__1753__auto__)) b__150 (clojure.core/chunk-buffer size__1754__auto__)] (if (loop [i__149 (clojure.core/int 0)] (if (clojure.core/< i__149 size__1754__auto__) (clojure.core/let [i (clojure.core/nth c__1753__auto__ i__149)] (do (clojure.core/chunk-append b__150 i) (recur (clojure.core/unchecked-inc i__149)))) true)) (clojure.core/chunk-cons (clojure.core/chunk b__150) (iter__147 (clojure.core/chunk-rest s__148))) (clojure.core/chunk-cons (clojure.core/chunk b__150) nil))) (clojure.core/let [i (clojure.core/first s__148)] (clojure.core/cons i (iter__147 (clojure.core/rest s__148))))))))))] (iter__1755__auto__ (range 10)))

Sin embargo, si hago lo mismo para doseq, entonces obtengo la misma forma de nuevo:

user=> (macroexpand '(doseq [i (range 10)] (println i)))
(doseq [i (range 10)] (println i))

Pero esta última expresión funciona en Clojure como se esperaba:

erdos.assert=>  (macroexpand '(doseq [i (range 10)] (println i)))
(loop* [seq_2318 (clojure.core/seq (range 10)) chunk_2319 nil count_2320 0 i_2321 0] (if (clojure.core/< i_2321 count_2320) (clojure.core/let [i (.nth chunk_2319 i_2321)] (do (println i)) (recur seq_2318 chunk_2319 count_2320 (clojure.core/unchecked-inc i_2321))) (clojure.core/when-let [seq_2318 (clojure.core/seq seq_2318)] (if (clojure.core/chunked-seq? seq_2318) (clojure.core/let [c__4917__auto__ (clojure.core/chunk-first seq_2318)] (recur (clojure.core/chunk-rest seq_2318) c__4917__auto__ (clojure.core/int (clojure.core/count c__4917__auto__)) (clojure.core/int 0))) (clojure.core/let [i (clojure.core/first seq_2318)] (do (println i)) (recur (clojure.core/next seq_2318) nil 0 0))))))

Quizás doseq es como una forma especial en Babashka? ¿Cuál es la razón de esta distinción en doseq?

¿Cómo debo modificar macroexpand para que se expandan todas las macros?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Parece que doseq es tratado como una forma especial en Babashka, lo que significa que no es una macro regular y no se expande de la misma manera que las macros regulares. La razón de esta distinción no está clara, pero podría deberse a detalles de implementación o razones de rendimiento.

    Para expandir todas las macros, incluyendo doseq, puedes usar la función clojure.walk/macroexpand-all en lugar de macroexpand. Esto expandirá recursivamente todas las macros en la forma dada, incluyendo formas especiales como doseq.

    Por ejemplo:

    (require '[clojure.walk :as walk])
    
    (walk/macroexpand-all '(doseq [i (range 10)] (println i)))
    

    Esto debería mostrar la forma completamente expandida de la macro doseq, incluyendo las construcciones de bucle y condicionales.

Comments are closed.