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?
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ónclojure.walk/macroexpand-all
en lugar demacroexpand
. Esto expandirá recursivamente todas las macros en la forma dada, incluyendo formas especiales comodoseq
.Por ejemplo:
Esto debería mostrar la forma completamente expandida de la macro
doseq
, incluyendo las construcciones de bucle y condicionales.