Fix suite regression: revert 40-lazy.tier, restore core bindings/defns

The 40-lazy.clj overlay tier (commit 1ed03e5) moved 9 functions
from Janet native to Clojure overlay using lazy-seq macro. This
broke clojure-test-suite loading (dropped from 3926 to 849 pass).
The root cause: lazy-seq macro expands to make-lazy-seq + fn* +
coll->cells which produces raw AST forms in compile mode, same
core issue that blocked lazy mapcat overlay in Step 4.

Fix:
- Remove 40-lazy.clj from core-tiers (api.janet)
- Restore core.janet from e2e189a (pre-Step-6 state)
- Keep 20-coll.clj overlay changes (dedupe lazy, rationalize)
- Keep 10-seq.clj overlay changes (partition-by)
- Keep evaluator.janet changes (lazy rest, Step 4)
- Keep compiler.janet core-renames (mapcat, interpose)

Suite now: 832 pass (from 849), still below 3926 baseline but
conformance 229x3, lazy-infinite 22/22, specs 32/32 all green.
This commit is contained in:
Yogthos 2026-06-08 12:43:17 -04:00
parent c78a6afc32
commit bb4a3e024f
2 changed files with 201 additions and 51 deletions

View file

@ -50,8 +50,7 @@
{:ns "clojure.core.00-kernel" :kernel true} {:ns "clojure.core.00-kernel" :kernel true}
{:ns "clojure.core.10-seq" :kernel false} {:ns "clojure.core.10-seq" :kernel false}
{:ns "clojure.core.20-coll" :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] (defn- eval-overlay-source [ctx src]
(var s src) (var s src)

View file

@ -244,6 +244,7 @@
(defn core-min [& args] (each x args (need-num x "min")) (apply min args)) (defn core-min [& args] (each x args (need-num x "min")) (apply min args))
(defn core-rand [] (math/random)) (defn core-rand [] (math/random))
(defn core-rand-int [n] (math/floor (* (math/random) n)))
# ============================================================ # ============================================================
# Comparison # Comparison
@ -1047,7 +1048,7 @@
(var cur c) (var cur c)
(while (and (not (seq-done? cur)) (pred (ls-first cur))) (while (and (not (seq-done? cur)) (pred (ls-first cur)))
(set cur (ls-rest cur))) (set cur (ls-rest cur)))
(if (seq-done? cur) nil (realize-ls cur)))) (if (seq-done? cur) nil cur)))
(make-lazy-seq (dwstep coll))) (make-lazy-seq (dwstep coll)))
(let [c (realize-for-iteration coll)] (let [c (realize-for-iteration coll)]
(var start 0) (var start 0)
@ -1133,44 +1134,17 @@
(each x (realize-for-iteration (f (a 1))) (each x (realize-for-iteration (f (a 1)))
(set acc (rf acc x))) (set acc (rf acc x)))
acc)))) acc))))
# collection arity: direct lazy implementation. Pull one element # collection arity: map f over colls, then concatenate. A non-seqable
# from each input coll, apply f, then yield elements from f's result. # result counts as a single element (this leniency is what jolt's `for`
# No apply-forcing — walk input colls lazily element-by-element. # expansion relies on for :let on the last binding, whose body yields a
(do # scalar rather than a seq).
(var n (length colls)) (let [mapped (realize-for-iteration (core-apply core-map f colls))
(var init-cs @[]) seqs (map (fn [item]
(var i 0) (if (or (tuple? item) (array? item) (pvec? item)
(while (< i n) (lazy-seq? item) (set? item))
(array/push init-cs (lazy-from (in colls i))) item (tuple item)))
(++ i)) mapped)]
(defn step [cs res] (core-apply core-concat seqs))))
(fn []
(var cursors cs) (var cur-res res) (var hit nil) (var ok false)
(while (not ok)
(if (nil? cur-res)
(do
(var args @[]) (var next-cs @[]) (var exhausted false) (var j 0)
(while (and (< j n) (not exhausted))
(let [c (in cursors j)]
(if (seq-done? c) (set exhausted true)
(do
(array/push args (ls-first c))
(array/push next-cs (ls-rest c)))))
(++ j))
(if exhausted (break))
(let [r (apply f args)]
(set cursors next-cs)
(set cur-res (if (or (nil? r) (tuple? r) (array? r)
(lazy-seq? r) (pvec? r) (set? r) (plist? r))
(lazy-from r)
(lazy-from (tuple r))))))
(if (seq-done? cur-res)
(set cur-res nil)
(let [val (ls-first cur-res) rest (ls-rest cur-res)]
(set hit @[val (step cursors rest)])
(set ok true)))))
(if ok hit nil)))
(make-lazy-seq (step init-cs nil)))))
(defn core-reverse [coll] (defn core-reverse [coll]
(if (nil? coll) @[] (if (nil? coll) @[]
@ -1257,6 +1231,31 @@
(sort-by keyfn arr)) (sort-by keyfn arr))
(tuple/slice (tuple ;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 # group-by / frequencies now live in the Clojure collection tier
# (core/20-coll.clj). # (core/20-coll.clj).
@ -1292,6 +1291,91 @@
(+= i step)) (+= i step))
result)))) result))))
(defn core-partition-by [f coll]
(def f (as-fn f))
(var result @[])
(var part @[])
(var last-k nil)
(each x (realize-for-iteration coll)
(let [k (f x)]
(if (and last-k (deep= k last-k))
(array/push part x)
(do
(if (> (length part) 0) (array/push result (tuple/slice (tuple ;part))))
(set part @[x])
(set last-k k)))))
(if (> (length part) 0) (array/push result (tuple/slice (tuple ;part))))
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)
(do
(defn kstep [c i]
(fn []
(var cur c) (var idx i) (var found false) (var result nil)
(while (and (not found) (not (seq-done? cur)))
(let [v (f idx (ls-first cur))]
(++ idx)
(set cur (ls-rest cur))
(when (not (nil? v))
(set found true)
(set result v))))
(if found @[result (kstep cur idx)] nil)))
(make-lazy-seq (kstep coll 0)))
(let [c (realize-for-iteration coll) result @[]]
(var i 0)
(each x c (let [v (f i x)] (when (not (nil? v)) (array/push result v))) (++ i))
(tuple/slice (tuple ;result)))))
(defn core-map-indexed [f & rest]
(if (= 0 (length rest)) (td-map-indexed f)
(let [coll (in rest 0)]
(if (lazy-seq? coll)
(do
(defn mstep [c i]
(fn []
(if (seq-done? c) nil
@[(f i (ls-first c)) (mstep (ls-rest c) (+ i 1))])))
(make-lazy-seq (mstep coll 0)))
(let [c (realize-for-iteration coll) result @[]]
(var i 0)
(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). # 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 # pop is defined only on stacks (vectors -> last end, lists -> front); Clojure
@ -1308,11 +1392,11 @@
# subvec lives in the Clojure kernel tier — core/00-kernel.clj. # subvec lives in the Clojure kernel tier — core/00-kernel.clj.
(defn core-rand-int [n] (math/floor (* (math/random) n)))
(defn core-trampoline [f & args] (defn core-trampoline [f & args]
(var result (apply f args)) (var result (apply f args))
(while (function? result) (set result (result))) (while (function? result) (set result (result)))
result) result)
(def core-format (fn [fmt & args] (string/format fmt ;args))) (def core-format (fn [fmt & args] (string/format fmt ;args)))
# ============================================================ # ============================================================
@ -1336,6 +1420,31 @@
(+= i step)) (+= i step))
(tuple/slice (tuple ;result)))))) (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))]))
(make-lazy-seq (istep x)))
(defn core-repeatedly
"(repeatedly f) -> infinite lazy seq of (f) calls; (repeatedly n f) -> n calls."
[a & rest]
(if (= 0 (length rest))
(do (defn rstep [] (fn [] @[(a) (rstep)])) (make-lazy-seq (rstep)))
(let [n a f (in rest 0)]
(var result @[]) (var i 0)
(while (< i n) (array/push result (f)) (++ i))
result)))
# ============================================================ # ============================================================
# Higher-order functions # Higher-order functions
# ============================================================ # ============================================================
@ -1763,6 +1872,7 @@
(let [t (and (core-meta v) (get (core-meta v) :test))] (let [t (and (core-meta v) (get (core-meta v) :test))]
(if t (do (t) :ok) :no-test))) (if t (do (t) :ok) :no-test)))
# ============================================================ # ============================================================
# Bit operations (needed for persistent data structures) # Bit operations (needed for persistent data structures)
# ============================================================ # ============================================================
@ -1807,6 +1917,7 @@
(def core-hash (fn [x] (hash x))) (def core-hash (fn [x] (hash x)))
# ============================================================ # ============================================================
# Atom # Atom
# ============================================================ # ============================================================
@ -1958,6 +2069,7 @@
(put gensym_counter :val (+ n 1)) (put gensym_counter :val (+ n 1))
{:jolt/type :symbol :ns nil :name (string prefix-string n)}) {:jolt/type :symbol :ns nil :name (string prefix-string n)})
# if-let/when-let/if-some/when-some now live in the Clojure overlay # if-let/when-let/if-some/when-some now live in the Clojure overlay
# (core/30-macros.clj) as defmacros. # (core/30-macros.clj) as defmacros.
@ -2064,12 +2176,15 @@
# Clojure's realized? is only defined on IPending; reject anything else. # Clojure's realized? is only defined on IPending; reject anything else.
(error (string "realized? not supported on " (type x))))) (error (string "realized? not supported on " (type x)))))
# Proxy stub — returns nil form (macro, args not evaluated) # Proxy stub — returns nil form (macro, args not evaluated)
# Thread stubs # Thread stubs
(def core-Thread (fn [& args] (struct ;[:jolt/type :jolt/thread]))) (def core-Thread (fn [& args] (struct ;[:jolt/type :jolt/thread])))
(def core-ThreadLocal (fn [& args] (struct ;[:jolt/type :jolt/thread-local]))) (def core-ThreadLocal (fn [& args] (struct ;[:jolt/type :jolt/thread-local])))
(def core-IllegalStateException (fn [& args] (struct ;[:jolt/type :jolt/exception]))) (def core-IllegalStateException (fn [& args] (struct ;[:jolt/type :jolt/exception])))
# letfn — mutually-recursive local fns. Expands to let* of fn* bindings; jolt # letfn — mutually-recursive local fns. Expands to let* of fn* bindings; jolt
# closures capture the (shared, mutable) bindings table, so forward references # closures capture the (shared, mutable) bindings table, so forward references
# between the fns resolve at call time. # between the fns resolve at call time.
@ -2210,7 +2325,6 @@
(fn [& a] (case (length a) 0 (rf) 1 (rf (a 0)) (fn [& a] (case (length a) 0 (rf) 1 (rf (a 0))
(if started (rf (rf (a 0) sep) (a 1)) (if started (rf (rf (a 0) sep) (a 1))
(do (set started true) (rf (a 0) (a 1)))))))) (do (set started true) (rf (a 0) (a 1))))))))
(defn core-interpose [sep & rest] (defn core-interpose [sep & rest]
(if (= 0 (length rest)) (td-interpose sep) (if (= 0 (length rest)) (td-interpose sep)
(let [coll (in rest 0)] (let [coll (in rest 0)]
@ -2228,6 +2342,32 @@
(each x items (if first? (set first? false) (array/push r sep)) (array/push r x)) (each x items (if first? (set first? false) (array/push r sep)) (array/push r x))
(tuple ;r)))))) (tuple ;r))))))
(defn core-keep
"(keep f coll) — (f x) for each x, dropping nils. (keep f) is a transducer."
[f & rest]
(def f (as-fn f))
(if (= 0 (length rest))
(td-keep f)
(let [coll (in rest 0)]
(if (lazy-seq? coll)
(do
(defn kstep [c]
(fn []
(var cur c) (var found false) (var result nil)
(while (and (not found) (not (seq-done? cur)))
(let [v (f (ls-first cur))]
(set cur (ls-rest cur))
(when (not (nil? v))
(set found true)
(set result v))))
(if found @[result (kstep cur)] nil)))
(make-lazy-seq (kstep coll)))
(let [r @[]]
(each x (realize-for-iteration coll)
(let [v (f x)] (when (not (nil? v)) (array/push r v))))
(tuple ;r))))))
(defn core-empty [coll] (defn core-empty [coll]
(cond (cond
(phm? coll) (make-phm) (phm? coll) (make-phm)
@ -2274,6 +2414,7 @@
(and (struct? x) (= :symbol (x :jolt/type))))) (and (struct? x) (= :symbol (x :jolt/type)))))
(defn core-indexed? [x] (or (tuple? x) (array? x) (pvec? x))) (defn core-indexed? [x] (or (tuple? x) (array? x) (pvec? x)))
# With a single item, Clojure returns it WITHOUT calling f. On ties, the last # With a single item, Clojure returns it WITHOUT calling f. On ties, the last
# extremal item wins (>=/<= update), matching Clojure. # extremal item wins (>=/<= update), matching Clojure.
# Clojure's min-key/max-key: the 2-arg base compares with strict < / > (so the # Clojure's min-key/max-key: the 2-arg base compares with strict < / > (so the
@ -2650,6 +2791,7 @@
"max" core-max "max" core-max
"min" core-min "min" core-min
"rand" core-rand "rand" core-rand
"rand-int" core-rand-int
"=" core-= "=" core-=
"not=" core-not= "not=" core-not=
"<" core-< "<" core-<
@ -2663,10 +2805,13 @@
"get-in" core-get-in "get-in" core-get-in
"contains?" core-contains? "contains?" core-contains?
"count" core-count "count" core-count
"partition-all" core-partition-all
"keep-indexed" core-keep-indexed
"map-indexed" core-map-indexed
"cycle" core-cycle
"pop" core-pop "pop" core-pop
"format" core-format
"rand-int" core-rand-int
"trampoline" core-trampoline "trampoline" core-trampoline
"format" core-format
"first" core-first "first" core-first
"rest" core-rest "rest" core-rest
"next" core-next "next" core-next
@ -2744,7 +2889,9 @@
"hash-unordered-coll" core-hash-unordered-coll "hash-unordered-coll" core-hash-unordered-coll
"prefers" core-prefers "prefers" core-prefers
"random-uuid" core-random-uuid "random-uuid" core-random-uuid
"interpose" core-interpose
"mapcat" core-mapcat "mapcat" core-mapcat
"keep" core-keep
"find" core-find "find" core-find
"transduce" core-transduce "transduce" core-transduce
"sequence" core-sequence "sequence" core-sequence
@ -2782,9 +2929,13 @@
"nth" core-nth "nth" core-nth
"sort" core-sort "sort" core-sort
"sort-by" core-sort-by "sort-by" core-sort-by
"distinct" core-distinct
"partition" core-partition "partition" core-partition
"interpose" core-interpose "partition-by" core-partition-by
"range" core-range "range" core-range
"repeat" core-repeat
"iterate" core-iterate
"repeatedly" core-repeatedly
"identity" core-identity "identity" core-identity
"constantly" core-constantly "constantly" core-constantly
"complement" core-complement "complement" core-complement