core: Stage 3 — leaf batch 3: empty/assoc-in/update-in + interpose/take-nth to the overlay

empty, assoc-in, and update-in move to 20-coll.clj as the canonical recursive
ports; interpose and take-nth move to the lazy tier WITH their canonical
transducer arities (volatile-based), so the seed's td-interpose/td-take-nth
helpers go too. (empty lazy-seq) is () now — the kernel fn returned a bare
host table for it.

keys/vals/empty? stay put for now: they're expander-coupled — 00-syntax's
when/and/or/cond/destructure expanders call them at expansion time, which
happens during the kernel-tier compile, before any later tier exists. They
move when early defns get the staged-recompile treatment macros already have.

26 new spec rows (incl. transducer arities through sequence/into and laziness
checks against (range)). Gate green: conformance 326x3, suite >= baseline,
full jpm test.
This commit is contained in:
Yogthos 2026-06-10 15:26:41 -04:00
parent 1340b7c52f
commit 780b6474ff
4 changed files with 107 additions and 64 deletions

View file

@ -732,3 +732,31 @@
([x y & more] (reduce min (min x y) more)))
(defn reverse [coll] (reduce conj (list) coll))
;; --- Phase 2 leaf batch 3 (jolt-ded) -----------------------------------------
;; An empty coll of the same category; sorted colls keep their comparator (the
;; value's own :empty op). Strings and scalars are nil, as in Clojure; a lazy
;; seq empties to () (the old kernel fn returned a host table for it).
(defn empty [coll]
(cond
(nil? coll) nil
(sorted? coll) ((get (jolt.host/ref-get coll :ops) :empty) coll)
(map? coll) {}
(set? coll) #{}
(vector? coll) []
(coll? coll) ()
:else nil))
(defn assoc-in [m [k & ks] v]
(if ks
(assoc m k (assoc-in (get m k) ks v))
(assoc m k v)))
(defn update-in [m ks f & args]
(let [up (fn up [m ks f args]
(let [[k & ks] ks]
(if ks
(assoc m k (up (get m k) ks f args))
(assoc m k (apply f (get m k) args)))))]
(up m ks f args)))