:quint/driver, a sixth key, and the rule it was added againstStatus: accepted, with the reservation below recorded rather than smoothed over.
One namespace, two specs. An application with a ledger spec and a cache spec
has one system namespace, and each spec wants a different init — a
different reset, a different fixture, a different amount of the world started.
Since 0008 that is an error: two vars claiming :quint/init
are :duplicate-init, whether they are in one namespace or across the :scan.
That error is right for a collision and wrong for this, and the two are
indistinguishable to the registry.
A sixth annotation key, optional, scoping an annotation to named drivers:
(ns app.system)
(defn open-ledger! {:quint/init true :quint/driver :ledger} [] ...)
(defn open-cache! {:quint/init true :quint/driver :cache} [] ...)
(defn post {:quint/action "post" :quint/driver #{:ledger :cache}} [n] ...)
(defn audit {:quint/action "audit"} [] ...) ; every driver
(q/defdriver ledger {:name :ledger :spec "spec/ledger.qnt" :scan '[app.system]})
(q/defdriver cache {:name :cache :spec "spec/cache.qnt" :scan '[app.system]})
:key-ns like the other five. A per-key qualifier is what
0007 refused and this does not reintroduce it.:name is :unnamed-driver. The
question "does this apply to me?" has no answer there, and both answers are
wrong in a way nothing would report.CLAUDE.md says the five keys are the whole vocabulary and that adding one needs a reason from a real spec, not a hypothetical one.
There is no such spec in this repository. Every driver here — bank,
tracked, checked, the two examples — scans a namespace serving exactly one
of them, and dev/bank/core.clj is shared by three drivers without conflict
because they want identical lifecycle. The case above is a real shape and a
common one, but it was reasoned about rather than met.
That was raised twice and the key was asked for anyway. It is the author's call, and this paragraph is here so that the call is legible later rather than looking like the rule was forgotten. The specific risk taken: a scoping key is much harder to remove than to add, and if the first real multi-spec application wants scoping by spec file or by module rather than by driver name, this key will be the wrong shape and will already have users.
Split the namespace. app.system-ledger and app.system-cache, each in
its own :scan. Needs no new vocabulary and works today. It was rejected as
the only answer because it makes the file layout follow the test tooling, which
is the thing this project keeps refusing to do everywhere else — the
application is not reshaped for the tool.
Driver-map :init / :halt overrides, symmetric with :actions and
:state. Rejected: an override says which function to call, not which of two
declarations was meant, and the override decision settled
that overriding does not silence an ambiguity. It would also leave the
annotations in the namespace still ambiguous and still erroring.
action, args, state, init, halt,
driver.:name joins the driver map, and is only meaningful when scoping is used.:unnamed-driver joins the error list.:empty-scan now means "no annotations at all", not "nothing for this
driver". A namespace whose annotations are all scoped elsewhere is legitimately
empty for this driver and must not be reported as the ^{...} (defn ...)
trap.Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |