core: Stage 3 — sorted collections are pure Clojure (canonical port)
sorted-map/sorted-map-by/sorted-set/sorted-set-by/sorted?/sorted-map?/
sorted-set?/subseq/rsubseq now live in their own overlay tier (25-sorted.clj).
A sorted coll is a tagged host table with a comparator-ordered :entries
vector, a 3-way :cmp, and the tier's op implementations ATTACHED to the value
(:ops map): the seed's conj/assoc/get/seq/count/... branches are each a
one-line call through (coll :ops), so the ops travel with the value — correct
across contexts, forks, and AOT images, no module-level hooks to re-wire.
The host surface grows by three minimal value primitives: jolt.host/
tagged-table, ref-put! (already there), and ref-get — a raw field read,
because plain get on a sorted coll IS the comparator lookup and reading
:entries with it recurses.
This fixes a pile of Clojure-correctness gaps the Janet kernel had:
- lookup/membership now go through the COMPARATOR: (contains? (sorted-set 1)
1.0) was a deep= scan, (conj (sorted-set 1) 1.0) and assoc of a
comparator-equal key now no-op/replace as in Clojure
- equality is representation-agnostic: (= (sorted-map :a 1) {:a 1}) and
(= (sorted-set 1 2) #{1 2}) were false
- iteration was broken: (map inc (sorted-set 3 1 2)) errored
(realize-for-iteration and coll->cells had no sorted branches)
- empty?/empty saw the host wrapper, not the collection: (empty? (sorted-map))
was false, (empty sc) returned a bare table; it now keeps the comparator
- sorted colls canonicalize as map keys; comparator fns may be boolean
predicates or 3-way (Clojure's fn->comparator)
- sorted-map throws on odd kv count; conj nil is a no-op
Also fixes jolt-h86 en passant: into-conj had no branch for sets (or sorted
colls) and silently returned the target unchanged — (into #{} [:a :b]) was
#{}. The fallback now folds conj. Regression rows in sets-spec.
sorted-spec grows to 77 rows (comparator-based membership, equality,
empty/rseq/printing, seq-fn interop, subseq/rsubseq on maps). Gate green:
conformance 326x3, suite 4577 (vs 4566 prior — the battery gained rows),
sorted+sets specs, full jpm test, bench at parity with main back-to-back
(4521ms vs 4619ms TOTAL under identical load).
This commit is contained in:
parent
d6c5552fda
commit
55a3ebf93f
9 changed files with 400 additions and 143 deletions
|
|
@ -9,7 +9,10 @@
|
|||
["set? true" "true" "(set? #{1})"]
|
||||
["set? false on vector" "false" "(set? [1])"]
|
||||
["count dedups" "3" "(count (set [1 1 2 3]))"]
|
||||
["equality order-indep" "true" "(= #{1 2 3} #{3 2 1})"])
|
||||
["equality order-indep" "true" "(= #{1 2 3} #{3 2 1})"]
|
||||
# jolt-h86: into-conj had no set branch and returned the set unchanged
|
||||
["into set" "#{:a :b}" "(into #{} [:a :b])"]
|
||||
["into non-empty set" "#{1 2 3}" "(into #{1} [2 3 2])"])
|
||||
|
||||
(defspec "set / operations"
|
||||
["conj adds" "#{1 2 3}" "(conj #{1 2} 3)"]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue