record field type hints -> per-field value types in inference (jolt-3ko)
A record field can carry a type hint — ^Vec3 (a defined record type) or ^:num — and the inference now resolves it so reading the field back yields that exact type instead of :any. A Vec3 stored in a Ray field reads out as Vec3, so the vec ops on field-read values prove their reads (bare-index). This is Stalin's per-slot type sets, but DECLARED rather than inferred: the exact shape is known up front. - deftype captures each field's :tag / :num metadata (was stripped) and passes it to make-deftype-ctor; the ctor registers per-field tags, resolving a record-type hint to its ctor-key (same-ns) so the inference can look it up directly. - call-ret-type builds a record's struct type with field types resolved from the hints, recursing into nested record types (depth-bounded for self/cyclic types). Measured: a nested-record read loop (:r (:origin ray)) runs 1.3s with ^Vec3 hints vs 7.1s without — 5.5x. This is the lever the ray tracer needed (vecs flow through container fields); records without it read back as :any and stay unproven.
This commit is contained in:
parent
872cea1c37
commit
840f699f54
3 changed files with 52 additions and 10 deletions
|
|
@ -286,6 +286,15 @@
|
|||
;; a seq of field keywords; spliced into a vector LITERAL below ([~@…]) so
|
||||
;; the analyzer sees a vector form, not a runtime pvec value.
|
||||
field-kws (map (fn [f] (keyword (name f))) fields)
|
||||
;; per-field TYPE HINT (jolt-3ko): ^Vec3 origin -> "Vec3" (a record type
|
||||
;; name), ^:num x -> "num", else nil. Lets the inference know a field's
|
||||
;; exact type up front, so reading it back carries that type (not :any) —
|
||||
;; the key to fast nested-record code. Spliced as a vector literal too.
|
||||
field-tags (map (fn [f] (let [mt (meta f)]
|
||||
(cond (and mt (:tag mt)) (:tag mt)
|
||||
(and mt (:num mt)) "num"
|
||||
:else nil)))
|
||||
fields)
|
||||
impl (fn [proto specs]
|
||||
`(extend-type ~tname ~proto
|
||||
~@(map (fn [spec]
|
||||
|
|
@ -295,7 +304,7 @@
|
|||
`(~(first spec) ~argv (let [~@binds] ~@(drop 2 spec)))))
|
||||
specs)))]
|
||||
`(do
|
||||
(def ~tname (make-deftype-ctor (quote ~tname) [~@field-kws]))
|
||||
(def ~tname (make-deftype-ctor (quote ~tname) [~@field-kws] [~@field-tags]))
|
||||
(def ~arrow ~tname)
|
||||
~@(map (fn [g] (impl (first g) (rest g))) (group-by-head body))
|
||||
~tname)))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue