jolt/.dirge/memory/PITFALLS.md
Yogthos 679cc1d4ef fix: persistent hash map — simple array-based, fully working
Replaced bit-trie HAMT with simple array-based implementation.
Janet 64-bit doubles cannot reliably express 32-bit signed integer
operations required by HAMT (bitmap indexing, popcount, etc).

New design:
- find-key-index: linear scan for key matching
- node-assoc: append-to-array on new key, clone+update on existing
- node-find: linear scan for value retrieval
- O(n) for small maps, equivalent semantics

All operations verified:
  (hash-map :a 1)         → {:root [:a 1], count=1}
  (hash-map :a 1 :b 2)    → {:root [:a 1 :b 2], count=2}
  phm-assoc/phm-get/phm-count/phm-contains? all correct
  Value replacement preserves count correctly
2026-06-02 13:41:47 -04:00

1.2 KiB

Janet struct? returns false for tables. Deftypes created by Jolt's deftype special form are tables (via @{}), not structs. So (struct? val) fails for deftype instances but (get val :jolt/deftype) works. This broke instance? check for persistent vector — fixed by changing from (and (struct? val) ...) to (get val :jolt/deftype). The . special form for deftype field access strips - prefix: (.-cnt obj)(get obj :cnt). § Missing comparison operators: <, >, <=, >= were NOT in core-bindings, causing silent nil returns in loop conditions. Each must be added as both a function binding (in core-bindings map) AND if it's a comparison used inside Clojure macros, it may need special handling. Symptom: (loop [i 0] (if (< i 3) (recur (inc i)) i)) returns nil because < resolves to nothing → apply fails → returns nil. § Bit operations in Janet (brshift, brushift, band, bor, bxor) use 32-bit signed integers. Values from (hash key) can exceed 32-bit range (>2^31). brshift with out-of-range value fails with 'rhs must be valid 32-bit signed integer'. Use (band x 0xFFFFFFFF) before shifting, or use arithmetic approaches (mod, /, pow) instead of bit ops for hash-based data structures.