refactor: registry pattern for jolt-hash + jolt-class (jolt-lmot)

Replace the set!-capture-and-rebind chains extending jolt-hash (3 sites: inst-time/
host-table/records) and jolt-class (3 sites: bigdec/natives-queue/host-table) with a
register-hash-arm! / register-class-arm! registry (the pattern already used by
register-str-render!). The base dispatcher walks its arms — disjoint types, so order
is immaterial — then falls to the base cases. The entry is stable, so the per-site
(def-var! "clojure.core" "class" …) re-points are gone.

Behaviour-preserving (runtime .ss, no re-mint): jinst hash, bigdec/queue/record
class, record hash, and a sorted-map hashing as its plain map all verified; make test
green, 0 new corpus divergences. First two of six dispatchers; get/=/pr-str follow.
This commit is contained in:
Yogthos 2026-06-23 23:01:30 -04:00
parent bcd752717e
commit d168d1195b
7 changed files with 34 additions and 19 deletions

View file

@ -70,7 +70,14 @@
(else #f))))
;; --- jolt hash — consistent with jolt= (for the HAMT) -----------------------
(define (jolt-hash x)
;; A host shim (records, host-table, inst-time, …) registers its type's hash via
;; register-hash-arm! instead of set!-wrapping jolt-hash — the arms are disjoint
;; types, checked before the base cases, so the full behavior is gathered here plus
;; the registry rather than scattered across a set! chain (cf. register-str-render!).
(define jolt-hash-arms '())
(define (register-hash-arm! pred handler)
(set! jolt-hash-arms (cons (cons pred handler) jolt-hash-arms)))
(define (jolt-hash-base x)
(cond
((jolt-nil? x) 0)
((keyword-t? x) (keyword-t-khash x))
@ -87,3 +94,8 @@
((jolt-sequential? x) (seq-hash x)) ; vector/list/seq hash alike (forward to seq.ss)
((jolt-coll? x) (jolt-coll-hash x)) ; map/set; forward to collections.ss
(else (equal-hash x))))
(define (jolt-hash x)
(let loop ((as jolt-hash-arms))
(cond ((null? as) (jolt-hash-base x))
(((caar as) x) ((cdar as) x))
(else (loop (cdr as))))))