Liking cljdoc? Tell your friends :D

co.multiply.remontoire.tee

Output capture: the root *out* and *err* tees and the per-eval banks they fill.

A tee sits at the one point every unbound deref of its var arrives at — the var's root — and discriminates per write, not per install: every write passes through to the original writer unchanged, and writes whose thread carries a bank in scope are additionally copied into that bank. It never diverts, never withholds, never attributes by wall-clock coincidence (§11). Host threads that bound *out* or *err* themselves never reach the root and never see the tee.

Both streams fill the same bank, interleaved in arrival order and unmarked — chronology beats channel separation, as in a terminal — so what *err* carries reaches the reader at last: warnings (a refer rejected in favor of an interned def says so only here — measured 2026-08-05, invisible then), reflection notes, stack traces from stray threads, anything host code mutters.

Output capture: the root `*out*` and `*err*` tees and the per-eval banks
they fill.

A tee sits at the one point every unbound deref of its var arrives at —
the var's root — and discriminates per write, not per install: every
write passes through to the original writer unchanged, and writes whose
thread carries a bank in scope are additionally copied into that bank.
It never diverts, never withholds, never attributes by wall-clock
coincidence (§11). Host threads that bound `*out*` or `*err*` themselves
never reach the root and never see the tee.

Both streams fill the *same* bank, interleaved in arrival order and
unmarked — chronology beats channel separation, as in a terminal — so
what `*err*` carries reaches the reader at last: warnings (a refer
rejected in favor of an interned def says so only here — measured
2026-08-05, invisible then), reflection notes, stack traces from
stray threads, anything host code mutters.
raw docstring

*bank*clj

The attribution key. Rides two rails (§11): scoping around eval-chain construction, which Quiescent re-establishes around every descendant task body — and a plain per-link binding, which Clojure conveyance carries into future/agent/bound-fn. One sc/ask covers both, because its fallback is a var deref and var derefs read thread bindings (measured 2026-08-04). Never bound outside those two sites.

The attribution key. Rides two rails (§11): `scoping` around eval-chain
construction, which Quiescent re-establishes around every descendant task
body — and a plain per-link `binding`, which Clojure conveyance carries
into `future`/`agent`/`bound-fn`. One `sc/ask` covers both, because its
fallback is a var deref and var derefs read thread bindings (measured
2026-08-04). Never bound outside those two sites.
raw docstring

bankclj

(bank)

A fresh bank: the tail of what one eval printed — completed lines in arrival order, each stored with its newline, plus the unterminated :partial — and how much has ever arrived, so trimming stays announceable. Lines, because whole entries are the unit a reader wants retained or dropped, and windowing (tail) falls out of the structure instead of out of string surgery.

A fresh bank: the tail of what one eval printed — completed lines in
arrival order, each stored with its newline, plus the unterminated
`:partial` — and how much has ever arrived, so trimming stays
announceable. Lines, because whole entries are the unit a reader
wants retained or dropped, and windowing (`tail`) falls out of the
structure instead of out of string surgery.
raw docstring

deposit!clj

(deposit! bank s)

Append s to bank. Writes assemble into newline-terminated lines — the unit of retention — and the cap trims whole lines from the front, oldest first. String surgery survives at one edge only: an entry that alone outgrows the cap is cut from its own front rather than dropped whole — the newest output is what a reader acts on (§5), and tail-keeping outranks entry purity when the two collide.

Append `s` to `bank`. Writes assemble into newline-terminated lines —
the unit of retention — and the cap trims whole lines from the front,
oldest first. String surgery survives at one edge only: an entry that
alone outgrows the cap is cut from its own front rather than dropped
whole — the newest output is what a reader acts on (§5), and
tail-keeping outranks entry purity when the two collide.
raw docstring

install!clj

(install!)

Swap the tees in at the roots of *out* and *err*. Idempotent; called by init!, so a host that never inits never has its roots touched. getRawRoot, not the deref: install runs on a caller's thread, where either var may well be thread-bound to something that is not the root at all.

Swap the tees in at the roots of `*out*` and `*err*`. Idempotent; called
by `init!`, so a host that never inits never has its roots touched.
`getRawRoot`, not the deref: install runs on a caller's thread, where
either var may well be thread-bound to something that is not the root
at all.
raw docstring

linesclj

(lines bank)

What bank retains, as a vector of lines — terminators stripped, the pending unterminated line last, and chars the cap already dropped announced as the first element, which is positionally honest: the drop happened at the head end, and composition reaching for the tail never meets it. Plain data, made for composing — take-last peeks, drop-last then take-last pages back, filter searches — where text is the verbatim reading form the responses carry. A view, not a consumption: the bank keeps what it keeps however it is read.

What `bank` retains, as a vector of lines — terminators stripped, the
pending unterminated line last, and chars the cap already dropped
announced as the first element, which is positionally honest: the
drop happened at the head end, and composition reaching for the tail
never meets it. Plain data, made for composing — `take-last` peeks,
`drop-last` then `take-last` pages back, `filter` searches — where
`text` is the verbatim reading form the responses carry. A view, not
a consumption: the bank keeps what it keeps however it is read.
raw docstring

sinceclj

(since bank from)

What arrived after position from (a cumulative-character count), as [text total] — the caller holds total as its next cursor. This is the heartbeat's read (§4): each beat drains what the eval said since the last one. A from the cap already trimmed past gets the drop announced, same as text.

What arrived after position `from` (a cumulative-character count), as
`[text total]` — the caller holds `total` as its next cursor. This is
the heartbeat's read (§4): each beat drains what the eval said since the
last one. A `from` the cap already trimmed past gets the drop announced,
same as `text`.
raw docstring

textclj

(text bank)

Everything bank holds, with the drop announced when the cap trimmed — a tail that silently posed as the whole output would be §5's nasty failure mode wearing a different hat.

Everything `bank` holds, with the drop announced when the cap trimmed —
a tail that silently posed as the whole output would be §5's nasty
failure mode wearing a different hat.
raw docstring

uninstall!clj

(uninstall!)

Restore the original root writers. Safe to call when not installed.

Restore the original root writers. Safe to call when not installed.
raw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close