core: three bug fixes — ifn?, prefer-method dispatch, reader comments in map values

ifn? (jolt-1vx) is the canonical IFn set in the overlay: fns, keywords,
symbols, maps (sorted included), sets, vectors, and vars — NOT lists. The
seed version said true for lists and false for struct maps and vars.
Mutable-mode caveat documented (vectors and lists share the array repr
there). 13 predicate rows.

Multimethod dispatch (jolt-heo) now collects EVERY isa-matching method key
and picks the dominant one — x dominates y when prefer-method'd over it or
(isa? x y) — and two matches with no dominant is an ambiguity ERROR, as in
Clojure. It used to take whichever key the table yielded first, silently
ignoring prefer-method. The prefers store upgrades to Clojure's
{x -> set-of-dominated} shape, shared between the dispatch closure and
prefer-method-setup via the var; prefers becomes a macro over a setup fn
(the store lives on the VAR — the multifn value can't carry it, so the old
fn read {} forever). 6 multimethod rows + the conformance row updated to
the canonical shape (335x3).

The reader (jolt-ou8) kept the pending KEY when a comment or #_ sits in a
map's VALUE slot: the old code dropped both, desyncing kv pairing — the
real value became the next key and the closing brace landed in value
position ('Unmatched closing brace'). Selmer's deps.edn (a '; for
development (REPL, etc)' comment between key and value) now parses; 6
reader rows incl. nested commented maps.

Gate: jpm exit 0, conformance 335x3, all tests passed.
This commit is contained in:
Yogthos 2026-06-10 21:03:14 -04:00
parent 19606730a3
commit c06af7c9f4
9 changed files with 133 additions and 21 deletions

View file

@ -129,6 +129,10 @@
["native bit-not" "-6" "(bit-not 5)"]
["native shifts" "[16 2]" "[(bit-shift-left 4 2) (bit-shift-right 8 2)]"]
### ---- multimethod preferences (jolt-heo) ----
["prefer-method breaks tie" ":rect"
"(do (derive :cm/sq :cm/rect) (derive :cm/sq :cm/shape) (defmulti cmf identity) (defmethod cmf :cm/rect [x] :rect) (defmethod cmf :cm/shape [x] :shape) (prefer-method cmf :cm/rect :cm/shape) (cmf :cm/sq))"]
### ---- HIGH: str semantics ----
["str nil empty" "\"\"" "(str nil)"]
["str concat nil" "\"a1\"" "(str \"a\" 1 nil)"]
@ -171,8 +175,9 @@
["remove-method" "nil" "(do (defmulti t6g :k) (defmethod t6g :b [x] 2) (remove-method t6g :b) (get (methods t6g) :b))"]
["remove-all-methods" "nil" "(do (defmulti t6h :k) (defmethod t6h :c [x] 3) (remove-all-methods t6h) (get (methods t6h) :c))"]
# NOTE: dispatch does not yet CONSULT prefers in ambiguous isa dispatch
# (jolt-bug filed) — this asserts prefer-method records the preference.
["prefer-method records" ":shape" "(do (defmulti t6p identity) (prefer-method t6p :rect :shape) (get (get (var t6p) :jolt/prefers) :rect))"]
# prefer-method records {x -> set-of-dominated} (Clojure's {x #{y}} shape;
# jolt-heo upgraded the store from single-value and dispatch consults it).
["prefer-method records" "true" "(do (defmulti t6p identity) (prefer-method t6p :rect :shape) (contains? (get (prefers t6p) :rect) :shape))"]
["instance? deftype" "true" "(do (deftype T6i [a]) (instance? T6i (->T6i 1)))"]
["instance? String" "true" "(instance? String \"s\")"]
["locking evals body" "3" "(locking :anything (+ 1 2))"]