core: jolt-b56 — lazy sequence (the laziness-coupled straggler)
(sequence xform coll) was eager (transduce into a tuple), so it hung on infinite input. Now it's a lazy buffered transducer pump: pulls one source element at a time, pushes it through the transducer's reducing fn into a buffer, and emits buffered outputs lazily — so (take 3 (sequence (map inc) (range))) works. Honors `reduced` (early stop) and runs the completion arity to flush stateful transducers. Normalizes the source via core-seq (walking a raw pvec/set would misfire — seq-done? uses length, which counts a pvec table's keys). The other jolt-b56 items stay native by design: sequential?/seqable? are representation-coupled and representation-mode-sensitive (jolt-1vx); realized? reads the tagged :realized flag; cat/eduction/transduce/halt-when/unreduced/ ensure-reduced are the transducer/Reduced kernel the issue says to keep native. Note: partition-all has no transducer (1-arg) arity, so (sequence (partition-all 2) …) errors — a pre-existing gap, unrelated to this change. Gate: conformance 249x3, lazy-infinite 44/44, fixpoint, self-host, specs+unit green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
da2b065f46
commit
c7378f4be0
2 changed files with 40 additions and 2 deletions
|
|
@ -878,11 +878,47 @@
|
||||||
(into-conj to (realize-for-iteration (in rest 0)))))
|
(into-conj to (realize-for-iteration (in rest 0)))))
|
||||||
|
|
||||||
(defn core-sequence
|
(defn core-sequence
|
||||||
"(sequence coll) or (sequence xform coll) — eager here (returns a seq/tuple)."
|
"(sequence coll) -> a seq of coll. (sequence xform coll) -> a LAZY seq of coll
|
||||||
|
transformed by xform: elements are pulled and pushed through the transducer one
|
||||||
|
at a time, with outputs buffered and emitted lazily — so it works over infinite
|
||||||
|
input (matching Clojure). Honors `reduced` (early stop) and runs the completion
|
||||||
|
arity to flush stateful transducers (e.g. partition-all)."
|
||||||
[a & rest]
|
[a & rest]
|
||||||
(if (= 0 (length rest))
|
(if (= 0 (length rest))
|
||||||
(core-seq a)
|
(core-seq a)
|
||||||
(tuple ;(core-transduce a (fn [& x] (case (length x) 0 @[] 1 (x 0) (do (array/push (x 0) (x 1)) (x 0)))) @[] (in rest 0)))))
|
(let [xform a
|
||||||
|
coll (in rest 0)
|
||||||
|
buf @[]
|
||||||
|
state @{:stopped false :completed false}
|
||||||
|
rf (fn [& args]
|
||||||
|
(case (length args)
|
||||||
|
0 buf
|
||||||
|
1 (in args 0)
|
||||||
|
(do (array/push (in args 0) (in args 1)) (in args 0))))
|
||||||
|
xf (xform rf)]
|
||||||
|
# Pull/complete until buf holds an output or the source is fully drained.
|
||||||
|
(defn ensure-buf [src]
|
||||||
|
(var s src)
|
||||||
|
(while (and (= 0 (length buf)) (not (state :stopped)) (not (seq-done? s)))
|
||||||
|
(let [r (xf buf (core-first s))]
|
||||||
|
(set s (core-rest s))
|
||||||
|
(when (core-reduced? r) (put state :stopped true))))
|
||||||
|
(when (and (= 0 (length buf)) (not (state :completed))
|
||||||
|
(or (state :stopped) (seq-done? s)))
|
||||||
|
(put state :completed true)
|
||||||
|
(xf buf)) # completion arity — flushes any buffered state
|
||||||
|
s)
|
||||||
|
(defn gen [src]
|
||||||
|
(fn []
|
||||||
|
(let [s (ensure-buf src)]
|
||||||
|
(if (= 0 (length buf)) nil
|
||||||
|
(let [val (in buf 0)]
|
||||||
|
(array/remove buf 0 1)
|
||||||
|
@[val (gen s)])))))
|
||||||
|
# core-seq normalizes to a tuple / lazy-seq / nil — all walkable by
|
||||||
|
# core-first/rest/seq-done?. (Walking a raw pvec/set would misfire:
|
||||||
|
# seq-done? uses length, which counts a pvec table's KEYS, not elements.)
|
||||||
|
(make-lazy-seq (gen (core-seq coll))))))
|
||||||
|
|
||||||
|
|
||||||
(defn coll->cells [c]
|
(defn coll->cells [c]
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,8 @@
|
||||||
["take 4 interleave range iterate" "(quote (0 10 1 11))" "(take 4 (interleave (range) (iterate inc 10)))"]
|
["take 4 interleave range iterate" "(quote (0 10 1 11))" "(take 4 (interleave (range) (iterate inc 10)))"]
|
||||||
["take 4 reductions + range" "(quote (0 1 3 6))" "(take 4 (reductions + (range)))"]
|
["take 4 reductions + range" "(quote (0 1 3 6))" "(take 4 (reductions + (range)))"]
|
||||||
["take 3 tree-seq infinite" "(quote (0 0 0))" "(take 3 (tree-seq (fn [_] true) (fn [n] [n]) 0))"]
|
["take 3 tree-seq infinite" "(quote (0 0 0))" "(take 3 (tree-seq (fn [_] true) (fn [n] [n]) 0))"]
|
||||||
|
["sequence xform lazy inf" "(quote (1 2 3))" "(take 3 (sequence (map inc) (range)))"]
|
||||||
|
["sequence comp xform inf" "(quote (2 4 6))" "(take 3 (sequence (comp (filter odd?) (map inc)) (range)))"]
|
||||||
["every? short-circuits on inf" "false" "(every? pos? (range))"]
|
["every? short-circuits on inf" "false" "(every? pos? (range))"]
|
||||||
["not-every? short-circuits on inf" "true" "(not-every? pos? (range))"]
|
["not-every? short-circuits on inf" "true" "(not-every? pos? (range))"]
|
||||||
["take 3 partition 2 range" "(quote ((0 1) (2 3) (4 5)))" "(take 3 (partition 2 (range)))"]
|
["take 3 partition 2 range" "(quote ((0 1) (2 3) (4 5)))" "(take 3 (partition 2 (range)))"]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue