The DIP swap point: a regex target language as data, plus the one gate every emitter passes through.
For a Construct a dialect cannot express, emit returns
(r/err :construct/unsupported …). It NEVER emits an approximation and never
drops a node. A :lookahead quietly discarded for RE2 produces a DIFFERENT
LANGUAGE that still compiles and still returns hits — the worst outcome
available, because nothing reports it.
emit is a plain function that checks capabilities and THEN calls
-render. An implementation supplies rendering only; it cannot skip,
weaken or forget the check, because it never sees it. One definition, N
implementations.
The dialect profile is an ARGUMENT throughout — resolved from the registry at call time, never captured at wiring time.
The DIP swap point: a regex target language as data, plus the one gate every emitter passes through. ## The substitutability contract For a Construct a dialect cannot express, `emit` returns `(r/err :construct/unsupported …)`. It NEVER emits an approximation and never drops a node. A `:lookahead` quietly discarded for RE2 produces a DIFFERENT LANGUAGE that still compiles and still returns hits — the worst outcome available, because nothing reports it. ## Why the gate is here and not in the emitter `emit` is a plain function that checks capabilities and THEN calls `-render`. An implementation supplies rendering only; it cannot skip, weaken or forget the check, because it never sees it. One definition, N implementations. The dialect profile is an ARGUMENT throughout — resolved from the registry at call time, never captured at wiring time.
(emit emitter construct)Result<String> for CONSTRUCT under EMITTER's dialect.
Refuses — with the missing capabilities named — rather than approximating.
Result<String> for CONSTRUCT under EMITTER's dialect. Refuses — with the missing capabilities named — rather than approximating.
(emit-as dialect-id construct)Result<String> for CONSTRUCT under the dialect registered as DIALECT-ID.
Result<String> for CONSTRUCT under the dialect registered as DIALECT-ID.
(emitter id)Result<IConstructEmitter> for ID.
Result<IConstructEmitter> for ID.
Renders a Construct the caller has already been cleared to emit.
Implementations do NOT gate — emit does that before calling here.
Renders a Construct the caller has already been cleared to emit. Implementations do NOT gate — `emit` does that before calling here.
(-render this construct)Result<String>: CONSTRUCT as a regex source string in this dialect.
Result<String>: CONSTRUCT as a regex source string in this dialect.
(dialect this)The Dialect this emitter renders for.
The Dialect this emitter renders for.
(missing-capabilities dialect construct)What CONSTRUCT needs that DIALECT does not provide. Empty = emittable.
What CONSTRUCT needs that DIALECT does not provide. Empty = emittable.
(register-emitter! emitter)Register EMITTER under its dialect id, replacing any prior one. Returns it. A profile that does not conform to the Dialect schema is refused.
Register EMITTER under its dialect id, replacing any prior one. Returns it. A profile that does not conform to the Dialect schema is refused.
(registered-emitters)Snapshot of {dialect-id -> IConstructEmitter}.
Snapshot of {dialect-id -> IConstructEmitter}.
(supports? dialect construct)Can DIALECT express CONSTRUCT? Decided from the shape — no compile.
Can DIALECT express CONSTRUCT? Decided from the shape — no compile.
(unregister-emitter! id)Drop the emitter registered under ID. Returns it, or nil.
Drop the emitter registered under ID. Returns it, or nil.
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 |