Repository navigation
Host classes are provided by declaration, not by a list in the runtime - #813
Merged
Merged
Conversation
RFC 0014. The runtime carried the mapping from host class names to the library
that installs them — jolt.crypto, io.github.jolt-lang/jolt-crypto, jolt.socket
and jolt.time, named in host-static.ss. Roughly 140 of that file's 552 lines
were the bookkeeping, in two parallel mechanisms (a bespoke one for java.time
and the general lib-class-providers) invoked side by side at five call sites,
plus a sixth copy in build.ss whose comment said it mirrors the runtime
predicates.
That was not untidiness. Core decided what a class MEANT, so providers were not
swappable and adding one needed a jolt release; and the list was hand-synced,
which the source said out loud — "When the library grows a class, add it here" —
next to a recorded instance of the bug it caused.
A provider cannot simply register itself as it loads: the miss happens BEFORE it
has loaded, which is the whole point of the mechanism. So the mapping arrives as
data, ahead of the load. A library declares it in its own deps.edn:
:jolt/provides {db.jdbc-shim ["java.sql.ResultSet" ...]}
jolt.deps collects it through the walk it already does for :jolt/native, and
apply-project! installs it before any user code compiles. Registration at load
is unchanged. Fully-qualified names only — the runtime derives the simple
spelling, which is what the old table got wrong by hand.
Core keeps only the classes core IMPLEMENTS: jolt.time.base's java.time value
types (RFC 0008) and jolt.socket's java.net surface, as core-class-providers
seeding the same table, carrying no coordinate because no dependency supplies
them. build.ss now asks lib-provider-for instead of restating its rules.
Two dependencies claiming one class is an error at resolve time naming both:
whichever won would decide what java.sql.Connection means program-wide, and the
loser's shim would be half-installed. A claim on a class the runtime already
implements is refused — the statics/ctor tables, not the hierarchy, which knows
names it does not implement.
Errors no longer name a library. Which library supplies java.sql is not the
runtime's to say, and a caller may write the shim themselves:
No dependency provides java.time.ZoneOffset — a concrete implementation of
the JDK classes must be provided.
Two unit tests pinned the old wording; they assert the general form now, plus a
third asserting no library is named, so the coupling cannot return as a string.
The deps-alias and build fixtures declare :jolt/provides like any other project —
the build one on its own :paths, which covers the project's-own-declaration case.
make test passes: 93 ci targets, 3 test targets.
This was referenced Sep 2, 2026
burinc
pushed a commit
to burinc/jolt
that referenced
this pull request
Sep 2, 2026
Since jolt jolt-lang#813 a host class is provided only through a library's :jolt/provides declaration, which jolt.deps reads from the library's deps.edn. Nine manifest entries put time's src directory on the path instead, so DateTimeFormatter and friends were unprovided and seven suites failed to load. The same :local-deps mechanism the crypto and yaml providers already use resolves time through its deps.edn. Claude-Session: https://claude.ai/code/session_019tGgRzPx3vtr5siPkKjjLE
This was referenced Sep 2, 2026
yogthos
added a commit
that referenced
this pull request
Sep 2, 2026
Closes the Unreleased section as 0.8.1. Four entries that PRs #806, #807, #808 and #815 filed under 0.8.0 after that tag was cut (socket errno, typed atomics, File.getParent at the root, namespaced-map prefixes) move into 0.8.1, where they shipped. Adds the entry #813 never wrote: host classes are provided by :jolt/provides declarations now, with the migration note for time and crypto pins (v0.0.8 / v0.0.5 declare theirs). Claude-Session: https://claude.ai/code/session_019tGgRzPx3vtr5siPkKjjLE
yogthos
added a commit
that referenced
this pull request
Sep 3, 2026
Since jolt #813 a host class is provided only through a library's :jolt/provides declaration, which jolt.deps reads from the library's deps.edn. Nine manifest entries put time's src directory on the path instead, so DateTimeFormatter and friends were unprovided and seven suites failed to load. The same :local-deps mechanism the crypto and yaml providers already use resolves time through its deps.edn.
yogthos
added a commit
that referenced
this pull request
Sep 3, 2026
Closes the Unreleased section as 0.8.1. Four entries that PRs #806, #807, #808 and #815 filed under 0.8.0 after that tag was cut (socket errno, typed atomics, File.getParent at the root, namespaced-map prefixes) move into 0.8.1, where they shipped. Adds the entry #813 never wrote: host classes are provided by :jolt/provides declarations now, with the migration note for time and crypto pins (v0.0.8 / v0.0.5 declare theirs).
burinc
pushed a commit
to burinc/jolt
that referenced
this pull request
Sep 4, 2026
jolt-lang#813) RFC 0014. The runtime carried the mapping from host class names to the library that installs them — jolt.crypto, io.github.jolt-lang/jolt-crypto, jolt.socket and jolt.time, named in host-static.ss. Roughly 140 of that file's 552 lines were the bookkeeping, in two parallel mechanisms (a bespoke one for java.time and the general lib-class-providers) invoked side by side at five call sites, plus a sixth copy in build.ss whose comment said it mirrors the runtime predicates. That was not untidiness. Core decided what a class MEANT, so providers were not swappable and adding one needed a jolt release; and the list was hand-synced, which the source said out loud — "When the library grows a class, add it here" — next to a recorded instance of the bug it caused. A provider cannot simply register itself as it loads: the miss happens BEFORE it has loaded, which is the whole point of the mechanism. So the mapping arrives as data, ahead of the load. A library declares it in its own deps.edn: :jolt/provides {db.jdbc-shim ["java.sql.ResultSet" ...]} jolt.deps collects it through the walk it already does for :jolt/native, and apply-project! installs it before any user code compiles. Registration at load is unchanged. Fully-qualified names only — the runtime derives the simple spelling, which is what the old table got wrong by hand. Core keeps only the classes core IMPLEMENTS: jolt.time.base's java.time value types (RFC 0008) and jolt.socket's java.net surface, as core-class-providers seeding the same table, carrying no coordinate because no dependency supplies them. build.ss now asks lib-provider-for instead of restating its rules. Two dependencies claiming one class is an error at resolve time naming both: whichever won would decide what java.sql.Connection means program-wide, and the loser's shim would be half-installed. A claim on a class the runtime already implements is refused — the statics/ctor tables, not the hierarchy, which knows names it does not implement. Errors no longer name a library. Which library supplies java.sql is not the runtime's to say, and a caller may write the shim themselves: No dependency provides java.time.ZoneOffset — a concrete implementation of the JDK classes must be provided. Two unit tests pinned the old wording; they assert the general form now, plus a third asserting no library is named, so the coupling cannot return as a string. The deps-alias and build fixtures declare :jolt/provides like any other project — the build one on its own :paths, which covers the project's-own-declaration case. make test passes: 93 ci targets, 3 test targets. Co-authored-by: Yogthos <yogthos@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements RFC 0014.
The runtime carried the mapping from host class names to the library that installs them —
jolt.crypto,io.github.jolt-lang/jolt-crypto,jolt.socket,jolt.time, named inhost-static.ss. About 140 of that file's 552 lines were that bookkeeping, in two parallel mechanisms (a bespoke one forjava.timeand the generallib-class-providers) invoked side by side at five call sites, plus a sixth copy inbuild.sswhose comment said it "mirrors the runtime predicates".That was not untidiness. Core decided what a class meant, so providers were unswappable and adding one needed a jolt release. And the list was hand-synced — the source said so out loud, next to a recorded instance of the bug it caused:
Why declaration, and not register-on-load
A provider cannot register itself as it loads: the miss happens before it has loaded, which is the entire purpose of the mechanism. So the mapping arrives as data, ahead of the load:
jolt.depscollects it through the walk it already does for:jolt/native;apply-project!installs it before any user code compiles. Registration at load is unchanged. Fully-qualified only — the runtime derives the simple spelling.What core keeps
Only the classes core implements:
jolt.time.base's java.time value types (RFC 0008) andjolt.socket'sjava.netsurface, ascore-class-providersseeding the same table, carrying no coordinate because no dependency supplies them.build.ssnow askslib-provider-forrather than restating its rules.Decisions
java.sql.Connectionmeans program-wide, and the loser's shim would be half-installed — registered for the classes nobody else claimed, silently absent for the rest.java.time.ZoneIdis in it soisa?answers correctly), and checking it rejected every provider for the classes the mechanism exists to serve.Errors no longer name a library
Which library supplies
java.sqlis not the runtime's to say, and a caller may write the shim themselves. Two unit tests pinned the old wording — which is how deliberate that message was; they assert the general form now, plus a third asserting no library is named, so the coupling cannot return as a string. A provider that is declared but raised while loading still names itself: that is the caller's own dependency read back from their owndeps.edn, and the fix is the opposite of adding something.Verified
make test— 93 ci targets, 3 test targets, clean. The gate caught four things targeted testing did not: the two deps-alias fixtures needed declarations; the lib coordinate is a symbol the failed-to-load message string-appends;build-appsupplies providers on its own:paths(the project's-own-declaration case); and the newjolt.hostseam had to be added tojolt-host-manifest.txt.Declarations are already merged in jolt-lang/db#17, jolt-lang/time#11 and jolt-lang/crypto#6.