fix: deftype now registers inline protocol/interface methods
Raw (deftype T [fields] Proto (method [this] body) ...) silently ignored its protocol body — only the constructor was created, so protocol dispatch on a deftype instance always failed (No method ... for T). defrecord worked only because its macro expanded the body into extend-type forms. deftype now does the same: emit an extend-type per protocol, wrapping each method body in a let that binds the type's fields from the instance. This is a real correctness fix (any deftype-with-protocols was broken) and unblocks SCI's sci.lang.Var (a deftype implementing vars/IVar) — the clojure.core aggregation map now gets past protocol dispatch. conformance 218/218, features 78/78, jank 120.
This commit is contained in:
parent
e52c445113
commit
4eead1ac0f
2 changed files with 33 additions and 0 deletions
|
|
@ -5,6 +5,7 @@
|
|||
{"_type":"issue","id":"jolt-x8s","title":"CRITICAL: collections not callable as IFn (vector/map/set)","status":"closed","priority":1,"issue_type":"bug","owner":"yogthos@gmail.com","created_at":"2026-06-04T17:46:14Z","created_by":"Yogthos","updated_at":"2026-06-04T17:50:54Z","closed_at":"2026-06-04T17:50:54Z","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
{"_type":"issue","id":"jolt-alz","title":"CRITICAL: self-referential lazy-seq/lazy-cat yields only literal prefix","status":"closed","priority":1,"issue_type":"bug","owner":"yogthos@gmail.com","created_at":"2026-06-04T17:46:13Z","created_by":"Yogthos","updated_at":"2026-06-04T18:09:15Z","closed_at":"2026-06-04T18:09:15Z","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
{"_type":"issue","id":"jolt-wec","title":"CRITICAL: multi-collection map returns unrealized thunk","status":"closed","priority":1,"issue_type":"bug","owner":"yogthos@gmail.com","created_at":"2026-06-04T17:46:12Z","created_by":"Yogthos","updated_at":"2026-06-04T18:06:02Z","closed_at":"2026-06-04T18:06:02Z","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
{"_type":"issue","id":"jolt-i3g","title":"Clear final 2 SCI bootstrap forms (Var/IVar collision + clojure.repl/template)","description":"namespaces.cljc forms 126/127 fail: (126) lang_stubs IVar collides with real vars.cljc IVar so unbind dispatch misses on sci.lang.Var; (127) clojure.repl + clojure.template namespaces missing. Fix: trim bootstrap stubs to let real modules own canonical protocols/types; port clojure.repl + clojure.template.","status":"open","priority":2,"issue_type":"task","owner":"yogthos@gmail.com","created_at":"2026-06-05T03:21:40Z","created_by":"Yogthos","updated_at":"2026-06-05T03:21:40Z","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
{"_type":"issue","id":"jolt-ns4","title":"Persistent collections + build-time mutable/immutable toggle","description":"Add JOLT_MUTABLE build flag (config.janet). Fix list-mutation bug (conj mutated original). Round 2: structural-sharing persistent vector (32-way trie) hooked into all core ops. Round 3: persistent lists / HAMT maps.","notes":"R1 (build flag + list mutation fix) and R2 (structural-sharing persistent vectors + mutable toggle) done \u0026 pushed (1eb2843). Immutable: conformance 206/206, features 71/71, jank 119. R3 (persistent linked lists) pending user decision: lists are immutable Janet arrays — O(1) sharing cons, O(n) conj.","status":"closed","priority":2,"issue_type":"feature","owner":"yogthos@gmail.com","created_at":"2026-06-04T22:15:39Z","created_by":"Yogthos","updated_at":"2026-06-04T23:20:46Z","closed_at":"2026-06-04T23:20:46Z","close_reason":"Done across 3 rounds (pushed a0c9696): build-time mutable/immutable toggle, structural-sharing persistent vectors (32-way trie), and persistent O(1)-prepend linked lists. Plus bit-clear/get-method and a batch of missing core fns. conformance 206/206, features 78/78, jank 120.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
{"_type":"issue","id":"jolt-gxr","title":"HIGH: aliased namespace calls (require :as) don't resolve (s/join)","status":"closed","priority":2,"issue_type":"bug","owner":"yogthos@gmail.com","created_at":"2026-06-04T18:09:58Z","created_by":"Yogthos","updated_at":"2026-06-04T18:45:52Z","closed_at":"2026-06-04T18:45:52Z","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
{"_type":"issue","id":"jolt-4z9","title":"HIGH: dispatch — multimethod :default, protocol-on-record, extend-protocol","status":"closed","priority":2,"issue_type":"bug","owner":"yogthos@gmail.com","created_at":"2026-06-04T18:09:57Z","created_by":"Yogthos","updated_at":"2026-06-04T18:40:43Z","closed_at":"2026-06-04T18:40:43Z","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
|
|
|
|||
|
|
@ -1137,6 +1137,38 @@
|
|||
arrow-name (string "->" ctor-name)]
|
||||
(ns-intern ns ctor-name ctor)
|
||||
(ns-intern ns arrow-name ctor)
|
||||
# Process inline protocol/interface methods (like defrecord):
|
||||
# (deftype T [fs] Proto (m [this] body) Proto2 (m2 [this] body))
|
||||
# Emit one extend-type per protocol, wrapping each method body in a
|
||||
# let that binds the type's fields from the instance (first param),
|
||||
# matching Clojure's field-in-scope semantics.
|
||||
(let [body (tuple/slice form 3)
|
||||
field-syms (map unwrap-meta-name fields-vec)]
|
||||
(var bi 0)
|
||||
(while (< bi (length body))
|
||||
(def elem (in body bi))
|
||||
(if (and (struct? elem) (= :symbol (elem :jolt/type)))
|
||||
(let [proto-sym elem
|
||||
et @[{:jolt/type :symbol :ns nil :name "extend-type"} type-name proto-sym]]
|
||||
(++ bi)
|
||||
(while (and (< bi (length body))
|
||||
(not (and (struct? (in body bi)) (= :symbol ((in body bi) :jolt/type)))))
|
||||
(let [spec (in body bi)
|
||||
mname (in spec 0)
|
||||
argv (in spec 1)
|
||||
mbody (tuple/slice spec 2)
|
||||
instance (in argv 0)
|
||||
field-binds @[]
|
||||
_ (each f field-syms
|
||||
(array/push field-binds f)
|
||||
(array/push field-binds @[{:jolt/type :symbol :ns nil :name "get"}
|
||||
instance (keyword (f :name))]))
|
||||
wrapped @[{:jolt/type :symbol :ns nil :name "let"}
|
||||
(tuple/slice (tuple ;field-binds)) ;mbody]]
|
||||
(array/push et @[mname argv wrapped]))
|
||||
(++ bi))
|
||||
(eval-form ctx bindings et))
|
||||
(++ bi))))
|
||||
(var-get (ns-intern ns ctor-name))))
|
||||
"new" (let [type-sym (in form 1)
|
||||
args (map |(eval-form ctx bindings $) (tuple/slice form 2))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue