Babashka 与 Clojure 中的 macroexpand doseq
macroexpand doseq in Babashka vs in Clojure
在 Babashka v0.6.2 中,我可以在 for 宏上调用 macroexpand,输出如下所示:
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)))
但是,如果我对 doseq 执行相同的操作,那么我会得到相同的表格:
user=> (macroexpand '(doseq [i (range 10)] (println i)))
(doseq [i (range 10)] (println i))
但后一个表达式在 Clojure 中按预期工作:
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))))))
也许 doseq
就像 Babashka 中的 special form? doseq
这个区分的原因是什么?
我应该如何修改 macroexpand
以便展开所有宏?
有些东西确实在解释器中被特殊处理,并没有作为常规宏来实现。这是早期的历史文物,当时 babashka 甚至不支持宏。这在未来可能会改变。
编辑:现在已经在 master 上修复了。感谢 erdos 的 PR。
在 Babashka v0.6.2 中,我可以在 for 宏上调用 macroexpand,输出如下所示:
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)))
但是,如果我对 doseq 执行相同的操作,那么我会得到相同的表格:
user=> (macroexpand '(doseq [i (range 10)] (println i)))
(doseq [i (range 10)] (println i))
但后一个表达式在 Clojure 中按预期工作:
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))))))
也许 doseq
就像 Babashka 中的 special form? doseq
这个区分的原因是什么?
我应该如何修改 macroexpand
以便展开所有宏?
有些东西确实在解释器中被特殊处理,并没有作为常规宏来实现。这是早期的历史文物,当时 babashka 甚至不支持宏。这在未来可能会改变。
编辑:现在已经在 master 上修复了。感谢 erdos 的 PR。