core: Stage 3 — leaf batch 4: sort-by + the rand family + char tables to the overlay

sort-by, rand-int, shuffle, random-uuid, char-escape-string, and
char-name-string move to 20-coll over the two host seams that stay (rand and
sort — they ARE the randomness/ordering primitives). Canonical upgrades ride
along: sort-by defaults its comparator to compare, so nil sorts FIRST (the
kernel fn used host ordering and put nil last); rand-int truncates toward
zero via int (the kernel fn floored, wrong for negative n); shuffle is a
pure-functional Fisher-Yates over vector assoc and rejects non-collections
(a string is seqable but not shuffleable, as on the JVM — the honest gate
caught that one); random-uuid builds over rand-int and validates through
parse-uuid; the char tables are char-keyed Clojure maps (Clojure's shape —
the seed keeps its private code-keyed copies for pr-render).

22 new spec rows. Gate: jpm test exit 0 verified, suite 4698 >= 4660, bench
parity with main back-to-back (4733 vs 4817).
This commit is contained in:
Yogthos 2026-06-10 16:30:17 -04:00
parent 17f2474be2
commit 3d7de8ff90
3 changed files with 85 additions and 43 deletions

View file

@ -134,3 +134,31 @@
["take-nth lazy" "(quote (0 3 6))" "(take 3 (take-nth 3 (range)))"]
["take-nth xform" "[1 3 5]" "(vec (sequence (take-nth 2) [1 2 3 4 5 6]))"]
["take-nth into" "[1 4]" "(into [] (take-nth 3) [1 2 3 4 5])"])
# Phase 2 leaf batch 4 (jolt-ded): sort-by (canonical: compare-defaulted, over
# the host sort seam), rand-int (canonical truncation via int), pure
# Fisher-Yates shuffle, random-uuid over parse-uuid, char tables as
# char-keyed Clojure maps. rand and sort stay: they ARE the host seams.
(defspec "clojure.core / leaf batch 4"
["sort-by keyfn" "[[1 :b] [2 :a]]" "(sort-by first [[2 :a] [1 :b]])"]
["sort-by string keys" "(quote (\"a\" \"bb\" \"ccc\"))" "(sort-by count [\"ccc\" \"a\" \"bb\"])"]
["sort-by comparator" "[3 2 1]" "(sort-by identity > [1 3 2])"]
["sort-by 3way cmp" "[3 2 1]" "(sort-by identity (fn [a b] (- b a)) [1 3 2])"]
["sort-by mixed nil" "[nil 1 2]" "(sort-by identity [2 nil 1])"]
["sort-by empty" "()" "(sort-by first [])"]
["sort-by nil coll" "()" "(sort-by first nil)"]
["rand-int range" "true" "(every? (fn [_] (let [r (rand-int 5)] (and (int? r) (<= 0 r 4)))) (range 50))"]
["rand-int zero" "0" "(rand-int 1)"]
["shuffle is permutation" "true" "(= (sort (shuffle [5 3 1 4 2])) [1 2 3 4 5])"]
["shuffle returns vector" "true" "(vector? (shuffle [1 2 3]))"]
["shuffle empty" "[]" "(shuffle [])"]
["shuffle non-coll throws" :throws "(shuffle 5)"]
["random-uuid is uuid" "true" "(uuid? (random-uuid))"]
["random-uuid v4 shape" "true" "(boolean (re-matches #\"[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}\" (str (random-uuid))))"]
["random-uuid distinct" "true" "(not= (random-uuid) (random-uuid))"]
["char-escape newline" "\"\\\\n\"" "(char-escape-string \\newline)"]
["char-escape quote" "true" "(= 2 (count (char-escape-string \\\")))"]
["char-escape none" "nil" "(char-escape-string \\a)"]
["char-name space" "\"space\"" "(char-name-string \\space)"]
["char-name newline" "\"newline\"" "(char-name-string \\newline)"]
["char-name none" "nil" "(char-name-string \\a)"])