Which host am I on, and what can it do?
koine's rule is that a seam either works or throws a named error — it never
quietly degrades. That is right, but it leaves a caller who WANTS to degrade
with no way to ask first, and the obvious workaround is not portable: catching
the throw needs Throwable on the JVM, cljgo and let-go, and go/error on
Glojure, so try/catch around a capability probe is itself host-specific
code — exactly what koine exists to prevent.
So the question gets a first-class answer. (supports? :process/spawn) is a
compile-time constant per host, and code that can do without a capability can
branch on it:
(if (host/supports? :process/spawn)
(talk-to-mcp-server)
(fall-back-to-http))
Capabilities are named :namespace/fn, matching where they live. An unknown
key answers false rather than throwing — a caller asking about a capability
koine has not heard of should take the safe branch, not crash.
Which host am I on, and what can it do?
koine's rule is that a seam either works or throws a named error — it never
quietly degrades. That is right, but it leaves a caller who WANTS to degrade
with no way to ask first, and the obvious workaround is not portable: catching
the throw needs `Throwable` on the JVM, cljgo and let-go, and `go/error` on
Glojure, so `try`/`catch` around a capability probe is itself host-specific
code — exactly what koine exists to prevent.
So the question gets a first-class answer. `(supports? :process/spawn)` is a
compile-time constant per host, and code that can do without a capability can
branch on it:
(if (host/supports? :process/spawn)
(talk-to-mcp-server)
(fall-back-to-http))
Capabilities are named `:namespace/fn`, matching where they live. An unknown
key answers false rather than throwing — a caller asking about a capability
koine has not heard of should take the safe branch, not crash.Everything this host can actually do, as a set. The three gaps are real and measured (2026-07-31), not assumed:
let-go has no byte-level file I/O (io/slurp decodes as text, and nothing in io/os/unix reads a file into a byte-array), no base64 over bytes (io/encode base64s the PRINTED form of a byte-array — silently wrong, so koine refuses it), and no streaming child (os/exec hands back an *exec.Cmd whose pipes are unreachable from Clojure), and no request timeout (a hung server hangs the caller). glj has everything EXCEPT a request timeout, for a different reason: setting net/http.Client's Timeout means assigning a struct field, which Glojure refuses.
Everything this host can actually do, as a set. The three gaps are real and
measured (2026-07-31), not assumed:
let-go has no byte-level file I/O (io/slurp decodes as text, and nothing in
io/os/unix reads a file into a byte-array), no base64 over bytes
(io/encode base64s the PRINTED form of a byte-array — silently
wrong, so koine refuses it), and no streaming child (os/exec hands
back an *exec.Cmd whose pipes are unreachable from Clojure), and no
request timeout (a hung server hangs the caller).
glj has everything EXCEPT a request timeout, for a different reason:
setting net/http.Client's Timeout means assigning a struct field,
which Glojure refuses.This host, as a keyword: :jvm, :cljgo, :glojure or :let-go.
This host, as a keyword: :jvm, :cljgo, :glojure or :let-go.
(supports? capability)True when this host implements capability (e.g. :process/spawn).
An unknown capability is false, never an error.
True when this host implements `capability` (e.g. :process/spawn). An unknown capability is false, never an error.
koine's support tier for this host (README):
:supported JVM, cljgo - a gap blocks a release :nice-to-have Glojure - implemented where straightforward :best-effort let-go - kept green, never gates a release
koine's support tier for this host (README): :supported JVM, cljgo - a gap blocks a release :nice-to-have Glojure - implemented where straightforward :best-effort let-go - kept green, never gates a release
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 |