seq fns are lazy by default, like Clojure (LazySeq, not eager-headed)
map/filter/remove/take/drop/concat/take-while/drop-while/mapcat/partition built an eager-headed cseq: the first element (and the fn application) ran at construction, so a side-effecting (map f coll) fired f immediately and (class (map …)) was PersistentList instead of LazySeq. This diverged from Clojure, which wraps the whole body in lazy-seq. It went unnoticed because the conformance gate certifies values, not realization — eager and lazy heads produce identical values — and unit.edn even baked PersistentList in as expected. test.check's for-all-takes-multiple-expressions (which counts side effects in a for-all body) exposed it. Wrap each native producer's result in a lazy-seq node so the body, incl. the first element, defers until forced — the forced cseq still has eager heads, so reduce/count/dorun/etc. force on walk and there's no per-element cost. dedupe's (seq coll) is moved inside its lazy-seq. A jolt LazySeq is now recognized by coll?/empty, the analyzer's form predicates (a macro can build its expansion with map), value-host-tags + instance? (LazySeq/ISeq/ Sequential), and reports clojure.lang.LazySeq. Kept the native Scheme implementations rather than porting Clojure's: a straight lazy-seq+cons port is 3x slower and Clojure's chunked fast path is 288x slower because jolt's chunk machinery is unoptimized (filed jolt-j9dz); the wrapped natives are Clojure-lazy at native speed. +12 corpus rows (laziness at construction, LazySeq type, both JVM-certified). make test + shakesmoke green, selfhost holds, 0 new divergences.
This commit is contained in:
parent
92368b49f1
commit
b879430618
10 changed files with 80 additions and 40 deletions
|
|
@ -105,8 +105,9 @@
|
|||
(if (null? colls)
|
||||
(td-mapcat f)
|
||||
;; lazily concat the per-element results — no seq->list, so mapcat over an
|
||||
;; infinite source stays lazy.
|
||||
(lazy-concat-seq (apply jolt-map f colls))))
|
||||
;; infinite source stays lazy; the outer lazy-seq node defers the first
|
||||
;; element so a side-effecting f does not fire at construction (LazySeq).
|
||||
(jolt-make-lazy-seq (lambda () (jolt-seq (lazy-concat-seq (apply jolt-map f colls)))))))
|
||||
|
||||
;; take-while / drop-while: 1-arg -> transducer; 2-arg -> a seq over the coll.
|
||||
(define (take-while-seq pred s)
|
||||
|
|
@ -118,7 +119,7 @@
|
|||
(define jolt-take-while
|
||||
(case-lambda
|
||||
((pred) (td-take-while pred))
|
||||
((pred coll) (take-while-seq pred (jolt-seq coll)))))
|
||||
((pred coll) (jolt-make-lazy-seq (lambda () (jolt-seq (take-while-seq pred (jolt-seq coll))))))))
|
||||
(define (drop-while-seq pred coll)
|
||||
(let loop ((s (jolt-seq coll)))
|
||||
(if (and (not (jolt-nil? s)) (jolt-truthy? (jolt-invoke pred (seq-first s))))
|
||||
|
|
@ -127,7 +128,7 @@
|
|||
(define jolt-drop-while
|
||||
(case-lambda
|
||||
((pred) (td-drop-while pred))
|
||||
((pred coll) (drop-while-seq pred coll))))
|
||||
((pred coll) (jolt-make-lazy-seq (lambda () (jolt-seq (drop-while-seq pred coll)))))))
|
||||
|
||||
;; partition: (partition n coll), (partition n step coll), or
|
||||
;; (partition n step pad coll). Only complete partitions of size n are kept;
|
||||
|
|
@ -135,9 +136,9 @@
|
|||
;; runs out). Each partition is a seq; the whole result is a lazy seq of seqs.
|
||||
(define jolt-partition
|
||||
(case-lambda
|
||||
((n coll) (partition* (->idx n) (->idx n) #f #f coll))
|
||||
((n step coll) (partition* (->idx n) (->idx step) #f #f coll))
|
||||
((n step pad coll) (partition* (->idx n) (->idx step) #t pad coll))))
|
||||
((n coll) (jolt-make-lazy-seq (lambda () (jolt-seq (partition* (->idx n) (->idx n) #f #f coll)))))
|
||||
((n step coll) (jolt-make-lazy-seq (lambda () (jolt-seq (partition* (->idx n) (->idx step) #f #f coll)))))
|
||||
((n step pad coll) (jolt-make-lazy-seq (lambda () (jolt-seq (partition* (->idx n) (->idx step) #t pad coll)))))))
|
||||
(define (take-n n s) ; -> (values list-of-first-n remaining-seq taken-count)
|
||||
(let loop ((n n) (s s) (acc '()))
|
||||
(if (or (fx<=? n 0) (jolt-nil? s))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue