core: transduce/eduction/->Eduction to the overlay; into stays seed (perf wall)

Round 5 of the seed shrink. transduce is the canonical 5-liner over reduce
(which already honors reduced and steps lazy seqs); eduction composes with
comp and stays eager into a vector (documented divergence, as before);
td-comp — eduction's last caller — is deleted from the seed. transient
accepts tuples now (reader vectors / map entries), so (into [] (first {:a 1}))
keeps working everywhere a vector does.

into was moved, benched, and moved back: the overlay call layers cost the
into-vec suite ~11% back-to-back (536 vs 480ms), the same per-call wall that
sent even?/odd? home in round 4. A transient conj! fast path didn't pay for
itself either (jolt call overhead dominates, not the per-element conj). The
seed keeps core-into + its private transduce machinery; the binding count
still drops by three.
This commit is contained in:
Yogthos 2026-06-11 13:52:35 -04:00
parent b9c7a623bb
commit 2557e3295f
3 changed files with 39 additions and 26 deletions

View file

@ -63,3 +63,15 @@
["reduce empty calls f" "0" "(reduce + [])"]
["reduce with-init" "16" "(reduce + 10 [1 2 3])"]
["reduce reduced immediate" ":x" "(reduce (fn [a x] (reduced :x)) :init [1 2 3])"])
# into/transduce/eduction are overlay fns now (seed-shrink round 5): into
# takes a transient fast path for vectors and preserves metadata; eduction
# stays eager (documented divergence).
(defspec "transducers / into & eduction (overlay)"
["into list prepends" "(quote (4 3 1 2))" "(into (quote (1 2)) [3 4])"]
["into sorted-map" "{1 :a, 2 :b}" "(into (sorted-map) [[2 :b] [1 :a]])"]
["into from map entry" "[:a 1]" "(into [] (first {:a 1}))"]
["into xform on map" "{:a 2}" "(into {} (map (fn [e] [(key e) (inc (val e))])) {:a 1})"]
["eduction multiple xforms" "[4]" "(into [] (eduction (filter odd?) (map inc) [2 3 4]))"]
["->Eduction" "[2 3]" "(->Eduction (map inc) [1 2])"]
["transduce no init uses (f)" "5" "(transduce (map inc) + [1 2])"])