feat: expand type-hint lookup specialization (^Record, get-form, checked mode, docs)
Builds on the ^:struct keyword-lookup hint: - ^TypeName for records. A tag naming a defrecord/deftype now resolves to the struct fast path: record instances are tables tagged :jolt/deftype (not :jolt/type), so a raw keyword get is correct for them. A new host contract fn record-type? detects a record by its ->Name constructor; a non-record tag (^String, ^long, ...) is ignored, as before. - (get m :k) and (get m :k default) now get the same inlined keyword lookup as (:k m): the representation guard fast path when unhinted, and the bare get when the subject is ^:struct/^Record. A variable/number/string key still falls through to core-get. The two call shapes share one emitter (emit-kw-lookup). - JOLT_CHECK_HINTS=1 turns a violated hint into a clear runtime error (naming the local and key) by keeping the guard and throwing on the tagged arm. It is off by default with zero cost to normal builds (a hinted lookup still emits a bare get), and is part of the image-cache fingerprint. This is the answer to "a lying hint is silent": opt into checking during development. - Docs: RFC 0004 records the design, soundness contract, and measurements; the reader spec gains S12b (hints are semantically transparent; jolt recognizes ^:struct and ^Record as lookup-optimization assertions). There is no Clojure keyword equivalent for "plain map / fast keyword access" (Clojure hints are class names), so ^:struct stays a jolt-specific flag, analogous to ^:dynamic. Verified: conformance 335/335 in all three modes and the full jpm test pass; a seeded ray-tracer render is byte-identical hinted vs unhinted; the struct-hint test covers record hints, the get-form, inline propagation, and the checked-mode error. Full render with hints holds at 13.3s -> 10.9s (1.22x).
This commit is contained in:
parent
c4be5d8a0e
commit
5f59c02b69
7 changed files with 276 additions and 54 deletions
|
|
@ -83,6 +83,16 @@ checks → UNVERIFIED (rows to add).
|
|||
- S12a. `^:kw form` ≡ `^{:kw true} form`; `^Sym form` ≡ `^{:tag Sym} form`;
|
||||
`^"str"` ≡ `^{:tag "str"} form`. Multiple `^` stack, rightmost innermost,
|
||||
merged left-over-right.
|
||||
- S12b. Type hints are semantically transparent: a hint MUST NOT change a
|
||||
program's result. Hints parse in every position they do in Clojure (params,
|
||||
`let` bindings, `def` names, return position, arbitrary forms) and are
|
||||
otherwise inert. As a non-normative optimization, jolt recognizes two hints
|
||||
on a local as an assertion that a constant-keyword lookup may skip its
|
||||
runtime representation guard: `^:struct` (a plain struct/record map) and
|
||||
`^Name` where `Name` is a `defrecord`/`deftype`. The assertion is the
|
||||
programmer's (an inaccurate hint yields a wrong lookup, like a wrong Clojure
|
||||
`^String`); `JOLT_CHECK_HINTS=1` turns a violated hint into an error at no
|
||||
cost to unchecked builds. See RFC 0004.
|
||||
- S13a. `#'ns/sym` MUST denote the same var as `(var ns/sym)`:
|
||||
`(= (var clojure.core/str) #'clojure.core/str)` is true.
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue