Clean up codebase: rename stdlib layer, strip porting residue, fix tooling
Rename src/jolt -> stdlib (the runtime-loaded layer; jolt-core stays the seed-baked layer) and update the loader / emit-image / doc paths. Drop dead code: the spike/ experiments, the duplicate clojuredocs-export.edn (json moves to tools/), the Janet-era jolt.http binding, and the orphaned persistent_vector.clj whose ns/path didn't even match. Strip porting residue from comments and docstrings across host/chez, jolt-core, stdlib, tests, and docs: internal issue ids, "Phase N" markers, and the "vs Janet" historical exposition, leaving present-tense descriptions and the real JVM-Clojure semantic contrasts. Same pass over the corpus suite labels. The seed is unchanged (docstrings/comments aren't emitted), so the self-host fixpoint and corpus are untouched. Port tools/spec_coverage.py off the dead janet probe to bin/joltc and regenerate coverage.md; drop the dead :host/janet rule from certify.clj and regenerate the conformance profile. Add docs/host-interop.md (the JVM shims and how to register your own host class from a library) and a writing-style note in CLAUDE.md. Stabilize the four racy concurrency corpus cases (future-cancel and agent send/send-off): give the future a sleeping body and the agent a slow action, so cancel reliably catches an in-flight future and deref reliably reads the pre-update snapshot. They certify deterministically now, so drop their :flaky allowlist entries and the orphaned legend.
This commit is contained in:
parent
c18f8087f0
commit
33eff7c7d8
112 changed files with 970 additions and 1621 deletions
|
|
@ -77,6 +77,6 @@ per-context opt-in, exactly how the SCI bootstrap now loads
|
|||
- Loading clj-ecosystem libraries via deps requires deciding their feature
|
||||
set; the deps loader currently inherits the process default — a future
|
||||
refinement is per-dependency feature configuration (filed with the deps
|
||||
work, jolt-dw4).
|
||||
work).
|
||||
- `.cljc` authors targeting jolt can write `:jolt` branches and rely on
|
||||
`:default` fallbacks.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# RFC 0005 — Structural collection-type inference
|
||||
|
||||
- **Status**: Implemented (jolt-5uj). Ray tracer 12.8s to 11.0s hint-free,
|
||||
- **Status**: Implemented. Ray tracer 12.8s to 11.0s hint-free,
|
||||
matching the explicit `^:struct` version; render checksum unchanged.
|
||||
- **Champions**: jolt maintainers
|
||||
- **Created**: 2026-06-13
|
||||
|
|
@ -14,7 +14,7 @@ function its parameter and return types, recursively. A keyword lookup returns
|
|||
the looked-up field's type, so nested access like `(:r (:direction ray))` is
|
||||
typed end to end. This unifies the two facts the current inference tracks
|
||||
inconsistently (a vector's element type, but not a map's field types), subsumes
|
||||
the existing inference phases (jolt-99x Phases 0 to 3) as special cases, and
|
||||
the existing inference passes as special cases, and
|
||||
closes the remaining ray-tracer gap without a hint. The system is a
|
||||
soft-typing-style inference: it never rejects a program, it assigns a concrete
|
||||
type only when it can prove one, and it falls back to `:any` (and the existing
|
||||
|
|
@ -22,7 +22,7 @@ runtime guard) everywhere else.
|
|||
|
||||
## Motivation
|
||||
|
||||
The inference added in jolt-99x specializes a collection access (drops the
|
||||
The existing inference specializes a collection access (drops the
|
||||
`:jolt/type` guard, emits `pv-count`, and so on) when it can prove the
|
||||
collection's type. It works, it is sound, and it is fully dynamic-fallback
|
||||
safe. But its type lattice grew ad hoc:
|
||||
|
|
@ -96,7 +96,7 @@ are depth 2 to 3, well inside the cap.
|
|||
|
||||
Inference is a forward pass producing `[type node']` for each IR node (the
|
||||
existing shape), threaded with a local type environment and the
|
||||
inter-procedural state from Phase 1. The rules are uniform over the structural
|
||||
inter-procedural state. The rules are uniform over the structural
|
||||
type:
|
||||
|
||||
- **Literals.** `{:k v ...}` with constant scalar keys and struct-safe values
|
||||
|
|
@ -115,9 +115,9 @@ type:
|
|||
signature: core fns from a fixed signature table (below), user fns from the
|
||||
inter-procedural fixpoint's inferred signature.
|
||||
|
||||
The Phase 1 inter-procedural fixpoint, recompile, escape gate, and closed-world
|
||||
assumption (RFC to follow / jolt-767) are unchanged. They now propagate
|
||||
structural types instead of flat tags.
|
||||
The inter-procedural fixpoint, recompile, escape gate, and closed-world
|
||||
assumption are unchanged. They now propagate structural types instead of flat
|
||||
tags.
|
||||
|
||||
## Core function signatures
|
||||
|
||||
|
|
@ -266,8 +266,8 @@ plus a signature table.
|
|||
tables and HOF handling).
|
||||
4. The back end keeps reading the use-site type to specialize (guard drop for
|
||||
`{:struct}`, `pv-count`/`pv-nth` for `{:vec}`), now uniformly.
|
||||
5. Keep the Phase 1 fixpoint, recompile, escape gate, and triggering as is; they
|
||||
propagate structural types.
|
||||
5. Keep the inter-procedural fixpoint, recompile, escape gate, and triggering as
|
||||
is; they propagate structural types.
|
||||
|
||||
The phases land incrementally behind the same optimization-mode gate, each
|
||||
verified against conformance (three modes), the full test gate, and the
|
||||
|
|
@ -298,5 +298,6 @@ ray-tracer benchmark, exactly as the current phases were.
|
|||
param/return inference is enough for the collection-specialization goal;
|
||||
full function types matter more for the type-checker (RFC 0006) and could be
|
||||
deferred.
|
||||
- **Closed-world boundary.** Inherited from Phase 1: param/return inference
|
||||
assumes the compiled unit is the whole program. Documented there; unchanged.
|
||||
- **Closed-world boundary.** Inherited from the inter-procedural pass:
|
||||
param/return inference assumes the compiled unit is the whole program.
|
||||
Documented there; unchanged.
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@
|
|||
|
||||
- **Status**: Implemented. Core-fn error domains (arithmetic on non-numbers,
|
||||
count/first/rest/next/seq/nth on non-seqable scalars), `JOLT_TYPE_CHECK=
|
||||
off|warn|error`. Follow-ups landed: bounded scalar **unions** (jolt-pz5) so a
|
||||
off|warn|error`. Follow-ups landed: bounded scalar **unions** so a
|
||||
use is reported only when every member is in the error domain; **user-fn
|
||||
error domains** behind `JOLT_TYPE_CHECK_USER` (jolt-zo1, closed-world);
|
||||
precise **file:line:col** locations (jolt-fqy). The checker is now one
|
||||
error domains** behind `JOLT_TYPE_CHECK_USER` (closed-world);
|
||||
precise **file:line:col** locations. The checker is now one
|
||||
inference walk (folded into `infer`), and is **on by default in direct-link
|
||||
builds** — where it piggybacks on the specialization inference for ~free —
|
||||
and opt-in (`JOLT_TYPE_CHECK`) in plain builds.
|
||||
|
|
@ -203,22 +203,22 @@ smallest high-confidence table (arithmetic and seq/count/nth/first), and grow.
|
|||
destroys trust. Mitigation: start tiny, test each entry against the runtime,
|
||||
grow slowly. Open question: derive the table from the same machinery the
|
||||
runtime uses, to avoid drift?
|
||||
- **Unions.** *Resolved (jolt-pz5).* The lattice has a bounded scalar union
|
||||
- **Unions.** *Resolved.* The lattice has a bounded scalar union
|
||||
`{:union #{T...}}` (cap 4); differing if-branches form a union instead of
|
||||
collapsing to `:any`, and a use is reported only when *every* member is in the
|
||||
error domain. Unions are opaque to structural specialization, so codegen is
|
||||
unchanged.
|
||||
- **User-function signatures.** *Resolved (jolt-zo1), opt-in.* Behind
|
||||
- **User-function signatures.** *Resolved, opt-in.* Behind
|
||||
`JOLT_TYPE_CHECK_USER`: the checker re-checks a registered non-redefinable
|
||||
user fn's body with one parameter bound to its concrete argument type; a
|
||||
diagnostic the all-`:any` body did not have means that argument is provably
|
||||
wrong. Monotonic, so still no false positives; closed-world, hence opt-in.
|
||||
- **Negative/never types.** *Resolved (jolt-wwy).* Calling a provably
|
||||
- **Negative/never types.** *Resolved.* Calling a provably
|
||||
non-callable value (`:num`/`:str` — keywords/maps/vectors/sets are IFn) is
|
||||
reported at the default level; wrong-arity to a registered single-fixed-arity
|
||||
user fn is reported under the `JOLT_TYPE_CHECK_USER` opt-in. A union callee is
|
||||
flagged only when every member is non-callable.
|
||||
- **Position vs intent.** *Resolved (jolt-fqy).* The reader records each list
|
||||
- **Position vs intent.** *Resolved.* The reader records each list
|
||||
form's absolute offset (identity-keyed, so positions survive macroexpansion
|
||||
exactly when the user's sub-form is spliced through); the analyzer stamps it
|
||||
onto `:invoke` nodes, the checker carries it into each diagnostic, and the
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue