jolt/host/chez/seed
Yogthos bfa2cbf49d Small maps preserve insertion order
jolt maps were HAMTs with hash iteration order; Clojure keeps small maps as
PersistentArrayMap (insertion order), converting to PersistentHashMap past a
threshold. Map literals, array-map, assoc, into/transient, merge, zipmap,
select-keys, update-keys/vals, frequencies and group-by now iterate in insertion
order for <=8 entries, matching the JVM. hash-map and >8-entry maps stay hash
order; sets stay hash order.

The pmap record gains an order field (the insertion-order key list, or #f once
hashed); the HAMT still backs the values so equality/hash/lookup are unchanged.
pmap-fold visits an array-mode map last-to-first so the runtime's cons-accumulate
idiom reconstructs insertion order without touching its many call sites, and
hash-mode output stays byte-identical; pmap-fold-fwd visits in order for the few
sites that build a value directly. Transient maps track insertion order and
promote to hash past max(8, source-count), matching TransientArrayMap.

The hash-map native-op retargets to a hash-order builder so (hash-map ...) stays
hash-ordered while {...} literals are ordered; syntax-quote builds maps via the
hash builder (Clojure expands `{...} to apply hash-map). The core overlay map
builders seed from {} instead of (hash-map) to keep order.

Threshold is 8 for any key (the keyword exception in newer Clojure isn't in
1.12.5). honeysql now passes 832/0/0; 19 JVM-certified corpus rows added.
2026-06-27 05:48:17 -04:00
..
image.ss Small maps preserve insertion order 2026-06-27 05:48:17 -04:00
prelude.ss Small maps preserve insertion order 2026-06-27 05:48:17 -04:00
README.md Docs: Chez-only, drop the Janet-era references and obsolete migration notes 2026-06-22 09:05:35 -04:00

Chez bootstrap seed

These two files are the bootstrap compiler for jolt — the seed that makes the build self-hosting:

  • prelude.ss — the clojure.core prelude (all tiers + clojure.string/walk/ template/edn/set/pprint) as Scheme def-var! forms.
  • image.ss — the compiler image (jolt.ir + jolt.analyzer + jolt.backend-scheme) as Scheme def-var! forms.

Both are generated, not hand-written. They are checked in because a fresh checkout must be able to build jolt-on-Chez using only Chez: host/chez/bootstrap.ss loads this seed, then rebuilds the prelude + image from the .clj/.ss sources via the on-Chez compiler (read → analyze → emit, all on Chez). The seed is a joint byte-fixpoint: rebuilding from an up-to-date seed reproduces it exactly. make selfhost (host/chez/selfcheck.sh) runs host/chez/bootstrap.ss and diffs the rebuilt artifacts against the checked-in seed.

Re-minting

When the seed sources change (the core tiers, the compiler namespaces, the host contract, the reader, emit-image.ss), the seed drifts and make selfhost fails. Re-mint it by running host/chez/bootstrap.ss and writing the freshly rebuilt prelude/image back to host/chez/seed/prelude.ss / host/chez/seed/image.ss, then commit the refreshed files.