Step 6: 40-lazy.clj tier — canonical CLJS implementations in overlay

New jolt-core/clojure/core/40-lazy.clj tier loads after 30-macros,
so lazy-seq macro is available. Ports 7 functions from CLJS core.cljs
(stripped of chunked-seq branches):

  distinct, keep, keep-indexed, map-indexed — lazy-seq + transducer arities
  cycle — idx modulo count via nth
  repeatedly, repeat, iterate — canonical CLJS lazy definitions
  partition-all — lazy with trailing partials via take+nthrest
  dedupe — lazy-seq, matches Clojure

interpose kept native (Janet core) — requires core-renames for
compile-mode resolution (drop + interleave + repeat chain cant
This commit is contained in:
Yogthos 2026-06-08 11:52:55 -04:00
parent 496bfb10cd
commit 1ed03e578f
4 changed files with 124 additions and 85 deletions

View file

@ -0,0 +1,114 @@
;; clojure.core — lazy tier. Canonical CLJS-based lazy seq fns.
;; Loaded after 30-macros.clj, so lazy-seq macro is available.
;;
;; Each fn ported from CLJS core.cljs, stripped of chunked-seq branches.
;; --- distinct ---
(defn distinct [coll]
(let [step (fn step [xs seen]
(lazy-seq
((fn [[f :as xs] seen]
(when-let [s (seq xs)]
(if (contains? seen f)
(recur (rest s) seen)
(cons f (step (rest s) (conj seen f))))))
xs seen)))]
(step coll #{})))
;; --- dedupe (lazy, canonical) ---
(defn dedupe [coll]
(let [step (fn step [s prev]
(lazy-seq
(let [s (seq s)]
(when s
(let [x (first s)]
(if (= x prev)
(step (rest s) prev)
(cons x (step (rest s) x))))))))]
(let [s (seq coll)]
(if s
(lazy-seq (cons (first s) (step (rest s) (first s))))
()))))
;; --- keep ---
(defn keep
([f]
(fn [rf]
(fn ([] (rf)) ([result] (rf result))
([result input]
(let [v (f input)]
(if (nil? v) result (rf result v)))))))
([f coll]
(lazy-seq
(when-let [s (seq coll)]
(let [x (f (first s))]
(if (nil? x)
(keep f (rest s))
(cons x (keep f (rest s)))))))))
;; --- keep-indexed ---
(defn keep-indexed
([f]
(fn [rf]
(let [ia (volatile! -1)]
(fn ([] (rf)) ([result] (rf result))
([result input]
(let [i (vswap! ia inc)
v (f i input)]
(if (nil? v) result (rf result v))))))))
([f coll]
(letfn [(keepi [idx coll]
(lazy-seq
(when-let [s (seq coll)]
(let [x (f idx (first s))]
(if (nil? x)
(keepi (inc idx) (rest s))
(cons x (keepi (inc idx) (rest s))))))))]
(keepi 0 coll))))
;; --- map-indexed ---
(defn map-indexed
([f]
(fn [rf]
(let [i (volatile! -1)]
(fn ([] (rf)) ([result] (rf result))
([result input] (rf result (f (vswap! i inc) input)))))))
([f coll]
(letfn [(mapi [idx coll]
(lazy-seq
(when-let [s (seq coll)]
(cons (f idx (first s)) (mapi (inc idx) (rest s))))))]
(mapi 0 coll))))
;; --- cycle ---
(defn cycle [coll]
(if-let [vals (seq coll)]
(let [n (count vals)]
(letfn [(cstep [i]
(lazy-seq
(cons (nth vals (mod i n)) (cstep (inc i)))))]
(cstep 0)))
()))
;; --- repeatedly ---
(defn repeatedly
([f] (lazy-seq (cons (f) (repeatedly f))))
([n f] (take n (repeatedly f))))
;; --- repeat ---
(defn repeat
([x] (lazy-seq (cons x (repeat x))))
([n x] (take n (repeat x))))
;; --- iterate ---
(defn iterate [f x]
(lazy-seq (cons x (iterate f (f x)))))
;; --- partition-all ---
(defn partition-all
([n coll] (partition-all n n coll))
([n step coll]
(lazy-seq
(when-let [s (seq coll)]
(cons (take n s) (partition-all n step (nthrest coll step)))))))

View file

@ -50,7 +50,8 @@
{:ns "clojure.core.00-kernel" :kernel true}
{:ns "clojure.core.10-seq" :kernel false}
{:ns "clojure.core.20-coll" :kernel false}
{:ns "clojure.core.30-macros" :kernel false}])
{:ns "clojure.core.30-macros" :kernel false}
{:ns "clojure.core.40-lazy" :kernel false}])
(defn- eval-overlay-source [ctx src]
(var s src)

View file

@ -96,6 +96,7 @@
"drop" "core-drop"
"take-while" "core-take-while"
"drop-while" "core-drop-while"
"interpose" "core-interpose"
"nth" "core-nth"
"mapcat" "core-mapcat"
"apply" "core-apply"

View file

@ -1257,31 +1257,6 @@
(sort-by keyfn arr))
(tuple/slice (tuple ;arr))))))
(defn core-distinct [coll]
(if (nil? coll) @[]
(if (lazy-seq? coll)
(do
(var seen @{})
(defn dstep [c]
(fn []
(var cur c) (var found false) (var result nil)
(while (and (not found) (not (seq-done? cur)))
(let [x (ls-first cur)]
(set cur (ls-rest cur))
(when (nil? (seen x))
(put seen x true)
(set found true)
(set result x))))
(if found @[result (dstep cur)] nil)))
(make-lazy-seq (dstep coll)))
(do
(var seen @{})
(var result @[])
(each x (realize-for-iteration coll)
(if (nil? (seen x))
(do (put seen x true) (array/push result x))))
(if (jvec? coll) (make-vec result) result)))))
# group-by / frequencies now live in the Clojure collection tier
# (core/20-coll.clj).
@ -1317,32 +1292,6 @@
(+= i step))
result))))
(defn core-partition-all [n coll]
(if (lazy-seq? coll)
(do
(defn pstep [c]
(fn []
(if (seq-done? c) nil
(do
(var part @[]) (var cur c) (var i 0)
(while (and (< i n) (not (seq-done? cur)))
(array/push part (ls-first cur))
(set cur (ls-rest cur))
(++ i))
@[(tuple/slice (tuple ;part)) (pstep cur)]))))
(make-lazy-seq (pstep coll)))
(let [c (realize-for-iteration coll)]
(var result @[]) (var i 0)
(while (< i (length c))
(var part @[]) (var j 0)
(while (and (< j n) (< (+ i j) (length c)))
(array/push part (in c (+ i j))) (++ j))
(array/push result (tuple/slice (tuple ;part)))
(+= i n))
result)))
(defn core-keep-indexed [f coll]
(def f (as-fn f))
(if (lazy-seq? coll)
@ -1379,14 +1328,6 @@
(each x c (array/push result (f i x)) (++ i))
(tuple/slice (tuple ;result)))))))
(defn core-cycle [coll]
(let [c (realize-for-iteration coll)]
(if (= 0 (length c))
(make-lazy-seq (fn [] nil))
(do
(defn cstep [i] (fn [] @[(in c (% i (length c))) (cstep (+ i 1))]))
(make-lazy-seq (cstep 0))))))
# reduce-kv now lives in the Clojure collection tier (core/20-coll.clj).
# pop is defined only on stacks (vectors -> last end, lists -> front); Clojure
@ -1432,16 +1373,6 @@
(+= i step))
(tuple/slice (tuple ;result))))))
(defn core-repeat
"(repeat x) -> infinite lazy seq of x; (repeat n x) -> n copies of x."
[a & rest]
(if (= 0 (length rest))
(do (defn rstep [] (fn [] @[a (rstep)])) (make-lazy-seq (rstep)))
(let [n a x (in rest 0)]
(var result @[]) (var i 0)
(while (< i n) (array/push result x) (++ i))
result)))
(defn core-iterate [f x]
"Lazy infinite sequence x, (f x), (f (f x)), ..."
(defn istep [v] (fn [] @[v (istep (f v))]))
@ -2337,6 +2268,7 @@
(fn [& a] (case (length a) 0 (rf) 1 (rf (a 0))
(if started (rf (rf (a 0) sep) (a 1))
(do (set started true) (rf (a 0) (a 1))))))))
(defn core-interpose [sep & rest]
(if (= 0 (length rest)) (td-interpose sep)
(let [coll (in rest 0)]
@ -2816,10 +2748,6 @@
"get-in" core-get-in
"contains?" core-contains?
"count" core-count
"partition-all" core-partition-all
"keep-indexed" core-keep-indexed
"map-indexed" core-map-indexed
"cycle" core-cycle
"pop" core-pop
"format" core-format
"rand-int" core-rand-int
@ -2901,9 +2829,7 @@
"hash-unordered-coll" core-hash-unordered-coll
"prefers" core-prefers
"random-uuid" core-random-uuid
"interpose" core-interpose
"mapcat" core-mapcat
"keep" core-keep
"find" core-find
"transduce" core-transduce
"sequence" core-sequence
@ -2941,12 +2867,9 @@
"nth" core-nth
"sort" core-sort
"sort-by" core-sort-by
"distinct" core-distinct
"partition" core-partition
"interpose" core-interpose
"range" core-range
"repeat" core-repeat
"iterate" core-iterate
"repeatedly" core-repeatedly
"identity" core-identity
"constantly" core-constantly
"complement" core-complement