Liking cljdoc? Tell your friends :D

beichte.core

Static effect inference for Clojure — no type system required.

Beichte (German: to confess) analyzes Clojure code via tools.analyzer.jvm and infers side-effect levels on a four-point lattice:

:pure < :local < :mutation < :io

Designed for compiler builders: validate that code is safe for AD, GPU compilation, parallelization, or CSE before transforming it.

Quick start:

(require '[beichte.core :as b])

;; Analyze expressions (fresh analysis each call — safe for REPL) (b/analyze '(+ 1 2)) ;; => :pure (b/analyze '(swap! a inc)) ;; => :mutation (b/analyze '(println "hi")) ;; => :io (b/analyze '(aset arr 0 42)) ;; => :local

;; Full descriptors with feature flags (b/analyze-full '(throw (Exception. "x"))) ;; => {:effect :pure, :flags #{:throws}}

;; Check if code is safe for a compilation target (b/compilable? :gpu '(+ 1 2)) ;; => true (b/compilable? :gpu '(throw (Exception. "x"))) ;; => false

;; Compiler pipelines: create a context to cache across calls (let [ctx (b/make-context)] (b/analyze '(foo x) ctx) ;; analyzes foo from source (b/analyze '(bar (foo x)) ctx) ;; foo already cached (b/analyze-var #'baz ctx)) ;; works for vars too

See beichte.effect for the lattice and flags, beichte.registry for the pre-annotated clojure.core entries, and beichte.analyze for the AST-walking inference engine.

Static effect inference for Clojure — no type system required.

Beichte (German: to confess) analyzes Clojure code via tools.analyzer.jvm
and infers side-effect levels on a four-point lattice:

  :pure < :local < :mutation < :io

Designed for compiler builders: validate that code is safe for AD,
GPU compilation, parallelization, or CSE before transforming it.

Quick start:

  (require '[beichte.core :as b])

  ;; Analyze expressions (fresh analysis each call — safe for REPL)
  (b/analyze '(+ 1 2))              ;; => :pure
  (b/analyze '(swap! a inc))        ;; => :mutation
  (b/analyze '(println "hi"))     ;; => :io
  (b/analyze '(aset arr 0 42))      ;; => :local

  ;; Full descriptors with feature flags
  (b/analyze-full '(throw (Exception. "x")))
  ;; => {:effect :pure, :flags #{:throws}}

  ;; Check if code is safe for a compilation target
  (b/compilable? :gpu '(+ 1 2))     ;; => true
  (b/compilable? :gpu '(throw (Exception. "x")))  ;; => false

  ;; Compiler pipelines: create a context to cache across calls
  (let [ctx (b/make-context)]
    (b/analyze '(foo x) ctx)      ;; analyzes foo from source
    (b/analyze '(bar (foo x)) ctx) ;; foo already cached
    (b/analyze-var #'baz ctx))     ;; works for vars too

See beichte.effect for the lattice and flags, beichte.registry for
the pre-annotated clojure.core entries, and beichte.analyze for the
AST-walking inference engine.
raw docstring

analyzeclj

(analyze expr)
(analyze expr ctx-or-opts)

Infer the effect level of a Clojure expression.

Returns one of: :pure, :local, :mutation, :io

Without context: fresh analysis each call (safe for REPL). With context: reuses cached var analysis results.

Infer the effect level of a Clojure expression.

Returns one of: :pure, :local, :mutation, :io

Without context: fresh analysis each call (safe for REPL).
With context: reuses cached var analysis results.
sourceraw docstring

analyze-fullclj

(analyze-full expr)
(analyze-full expr ctx-or-opts)

Infer the full effect descriptor of a Clojure expression.

Returns {:effect :level, :flags #{...}} where flags are orthogonal properties like :throws, :random, :reflects, :allocates.

Infer the full effect descriptor of a Clojure expression.

Returns {:effect :level, :flags #{...}} where flags are orthogonal
properties like :throws, :random, :reflects, :allocates.
sourceraw docstring

analyze-nsclj

(analyze-ns ns-sym)
(analyze-ns ns-sym ctx-or-opts)

Analyze all public vars in a namespace.

Returns {var → effect-level}.

Analyze all public vars in a namespace.

Returns {var → effect-level}.
sourceraw docstring

analyze-ns-fullclj

(analyze-ns-full ns-sym)
(analyze-ns-full ns-sym ctx-or-opts)

Analyze all public vars and return {var → descriptor}.

Analyze all public vars and return {var → descriptor}.
sourceraw docstring

analyze-varclj

(analyze-var v)
(analyze-var v ctx-or-opts)

Infer the effect level of a var by analyzing its source.

Returns one of: :pure, :local, :mutation, :io

Infer the effect level of a var by analyzing its source.

Returns one of: :pure, :local, :mutation, :io
sourceraw docstring

analyze-var-fullclj

(analyze-var-full v)
(analyze-var-full v ctx-or-opts)

Infer the full effect descriptor of a var.

Returns {:effect :level, :flags #{...}}.

Infer the full effect descriptor of a var.

Returns {:effect :level, :flags #{...}}.
sourceraw docstring

budget-forclj

(budget-for target)

Return the effect budget for a compilation target.

Return the effect budget for a compilation target.
sourceraw docstring

compilable?clj

(compilable? target expr)
(compilable? target expr ctx-or-opts)

True if an expression is within the effect budget for a compilation target.

Checks both state effect budget and feature flag support.

Targets and their budgets: :ad, :cse — :pure (no effects at all) :gpu, :simd — :local (thread-local mutation OK) :parallel — :local :sequential — :io (anything goes) :inline — :io (anything goes)

GPU also rejects :throws and :reflects flags.

True if an expression is within the effect budget for a compilation target.

Checks both state effect budget and feature flag support.

Targets and their budgets:
  :ad, :cse       — :pure (no effects at all)
  :gpu, :simd     — :local (thread-local mutation OK)
  :parallel       — :local
  :sequential     — :io (anything goes)
  :inline         — :io (anything goes)

GPU also rejects :throws and :reflects flags.
sourceraw docstring

default-registryclj

(default-registry)

Return the default registry with pre-annotated clojure.core and Java entries.

Return the default registry with pre-annotated clojure.core and Java entries.
sourceraw docstring

extend-registryclj

(extend-registry reg entries)

Extend a registry with additional entries.

Extend a registry with additional entries.
sourceraw docstring

filter-compilableclj

(filter-compilable target vars)
(filter-compilable target vars ctx-or-opts)

Filter vars to those within the effect budget for a compilation target.

Filter vars to those within the effect budget for a compilation target.
sourceraw docstring

flagsclj

Known feature flags: #{:throws :random :reflects :allocates}

Known feature flags: #{:throws :random :reflects :allocates}
sourceraw docstring

joinclj

(join a b)

Least upper bound of two effects.

Least upper bound of two effects.
sourceraw docstring

levelsclj

Effect levels in ascending order: [:pure :local :mutation :io]

Effect levels in ascending order: [:pure :local :mutation :io]
sourceraw docstring

make-contextclj

(make-context)
(make-context {:keys [registry]})

Create an analysis context that caches results across calls.

For REPL use, omit the context — each call analyzes fresh. For compiler pipelines, create one context per pass and reuse it.

Options: :registry — custom effect registry (default: default-registry)

Create an analysis context that caches results across calls.

For REPL use, omit the context — each call analyzes fresh.
For compiler pipelines, create one context per pass and reuse it.

Options:
  :registry — custom effect registry (default: default-registry)
sourceraw docstring

make-registryclj

(make-registry entries)

Create a custom registry from a map of {entry → effect-level}. Entries can be vars, [class method] pairs, or class name strings.

Create a custom registry from a map of {entry → effect-level}.
Entries can be vars, [class method] pairs, or class name strings.
sourceraw docstring

within-budget?clj

(within-budget? budget eff)

True if effect level is at most as effectful as budget.

True if effect level is at most as effectful as budget.
sourceraw 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