Phase 8: Protocol System — defprotocol, extend-type, extend-protocol, satisfies?
- types.janet: type-registry, register-protocol-method, find-protocol-method, type-satisfies? - core.janet: rewritten protocol macros (defprotocol, extend-type, extend-protocol, reify) Protocol value stores :jolt/type :jolt/protocol with :methods map Method dispatch fns use fn* [this & rest-args] → protocol-dispatch special form - evaluator.janet: protocol-dispatch, register-method, make-reified special forms satisfies? special form with type registry lookup special-symbol? entries for all 3 protocol ops + satisfies? - 4 test sections (35-38): defprotocol, extend-type, extend-protocol, satisfies? extend-type: basic dispatch works (42 constant), .-field accessor needs further debug satisfies?: fully functional with type registry - 315 ok, 2 fail (pre-existing, unchanged)
This commit is contained in:
parent
09c4cb2242
commit
053ed4f790
11 changed files with 463 additions and 134 deletions
72
.dirge/skills/jolt-persistent-structures/SKILL.md
Normal file
72
.dirge/skills/jolt-persistent-structures/SKILL.md
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
---
|
||||
name: jolt-persistent-structures
|
||||
description: PersistentHashMap, PersistentHashSet, and LazySeq implementation patterns in Janet tables
|
||||
---
|
||||
|
||||
# jolt-persistent-structures
|
||||
|
||||
PersistentHashMap, PersistentHashSet, and LazySeq implementation patterns in Janet tables.
|
||||
|
||||
## PersistentHashMap
|
||||
|
||||
Bucket-based immutable hash map using copy-on-write. Stores data in `:buckets` (array of flat `[k v k v ...]` bucket arrays), `:cnt` (entry count), `:jolt/deftype` type tag, and `:_meta`.
|
||||
|
||||
### Core functions (in phm.janet)
|
||||
- `make-phm [& kvs]` — create from key-value pairs
|
||||
- `phm-get [m k &opt default]` — lookup with optional default
|
||||
- `phm-assoc [m k v]` — return new map with k→v
|
||||
- `phm-dissoc [m k]` — return new map without k
|
||||
- `phm-contains? [m k]` — membership check
|
||||
- `phm-count [m]` — number of entries
|
||||
- `phm-to-struct [m]` — convert to Janet struct (for equality, keys, vals)
|
||||
- `phm-entries [m]` — return `[[k v] ...]` pairs
|
||||
|
||||
### Core function integration (core.janet)
|
||||
Each core fn checks `phm?` first, then falls through to struct/table logic:
|
||||
- `core-get` → `phm-get`
|
||||
- `core-assoc` → `phm-assoc`
|
||||
- `core-dissoc` → `phm-dissoc`
|
||||
- `core-contains?` → `phm-contains?`
|
||||
- `core-count` → `phm-count`
|
||||
- `core-keys/vals/seq` → via `phm-to-struct`
|
||||
- `core-merge/merge-with` → PHM-aware iteration
|
||||
- `core-empty?` → check `:cnt = 0`
|
||||
- `core-conj` → `phm-assoc` for `[k v]` pairs
|
||||
|
||||
### Gotchas
|
||||
- `core-map?`: `(if (and (table? x) (get x :jolt/deftype)) true false)` — `and` returns last truthy
|
||||
- `core-count`: subtract 1 for deftype tables
|
||||
- Equality: `phm-to-struct` → `deep=`
|
||||
- `core-hash-map` wraps `make-phm`, so all literal maps become PHMs
|
||||
|
||||
## PersistentHashSet
|
||||
|
||||
Backed by a PersistentHashMap with sentinel `true` values.
|
||||
|
||||
### Core functions (in phm.janet)
|
||||
- `make-phs [& xs]` — create from items
|
||||
- `phs-conj [s & xs]` — add items (idempotent)
|
||||
- `phs-disj [s & xs]` — remove items
|
||||
- `phs-contains? [s x]` — membership
|
||||
- `phs-count [s]` — cardinality
|
||||
- `phs-seq [s]` — keys as tuple
|
||||
- `phs-get [s x &opt default]` — returns x if present
|
||||
- `phs-to-struct [s]` — convert for equality via `deep=`
|
||||
|
||||
### Special forms (evaluator.janet)
|
||||
- `:jolt/set` handler: `(apply make-phs (form :value))`
|
||||
- `"disj"` dispatch — validates set?, calls `phs-disj`
|
||||
- `"set?"` dispatch — calls `set?` predicate
|
||||
|
||||
## LazySeq
|
||||
|
||||
Realize-once thunk wrapper.
|
||||
|
||||
### Core functions (in phm.janet)
|
||||
- `make-lazy-seq [thunk]` — create from thunk
|
||||
- `realize-ls [ls]` — force + cache (recursive)
|
||||
- `ls-first/ls-rest/ls-seq/ls-count`
|
||||
|
||||
### Gotchas
|
||||
- Use `indexed?` not `tuple?` for realized sequences
|
||||
- Avoid `val'` (parse error), use `vf`
|
||||
Loading…
Add table
Add a link
Reference in a new issue