Liking cljdoc? Tell your friends :D

vaelii.impl.source-identity

The source identity: a digest of the engine source that derives belief. A belief image is stamped with it, and an open installs the image only when its own source identity is equal, so an image is never installed by code that would derive a different belief from the same records.

Which files

The digest covers the transitive closure of roots over three kinds of edge, each read from the source files themselves rather than from the loaded namespaces:

  • the ns form's :require, :use and :import clauses — an imported deftype or defrecord class names the namespace that defines it;
  • every fully-qualified symbol under a quote in code. These are the edges no ns form states: the requiring-resolve targets and the fixed symbol tables that name them (vaelii.core's calculi, reasoners and solvers, vaelii.impl.imperative's do/ handlers, vaelii.impl.wiring's three entry points).

The walk follows vaelii.core and vaelii.impl.* and nothing else. Code from outside those prefixes — a registered prover or evaluatable, a foreign plugin — is not in the digest; vaelii.impl.belief-image refuses to write or install an image for a KB that runs any.

What is hashed

Each file is read as forms, and the forms are hashed with four things removed: comments, (comment …) blocks, docstrings, and the reader's position metadata. An edit that changes only prose therefore leaves the digest unchanged. An edit to code, or to metadata the compiler reads (^:dynamic, ^:const, a type hint), changes it.

The reader mints a fresh name on every read for two kinds of symbol: a syntax-quote auto-gensym (x#) and an anonymous-fn argument (%). Both are renumbered in order of first appearance within their top-level form, so two reads of one file hash alike. Aliases, classes and vars are read through a *reader-resolver* that resolves each to itself, so a file reads the same way whether or not its namespace is loaded.

A namespace with no source

The Clojars jar, the uberjar and a source checkout all carry the .clj files, so every namespace is normally read as forms. A namespace on the classpath only as compiled classes contributes the digest of the code it loads from instead: the whole jar its __init class sits in, or every class file of the namespace in a class directory. A namespace compiles to one class per fn, so no single class file covers its code. The jar digest changes with any rebuild, which is conservative: an image is discarded more often, never installed under different code.

Libraries

Each third-party library the closure requires or imports contributes the file name of the jar its code loads from (nippy-3.5.0.jar), and the file name carries the version. A library loaded from a directory rather than a jar contributes its namespace or class name. JDK classes contribute nothing.

Nothing here memoizes: a REPL can change a source file between two calls, and the digest describes the files as they stand at the call.

The **source identity**: a digest of the engine source that derives belief.  A belief
image is stamped with it, and an open installs the image only when its own source
identity is equal, so an image is never installed by code that would derive a different
belief from the same records.

## Which files

The digest covers the transitive closure of `roots` over three kinds of edge, each read
from the source files themselves rather than from the loaded namespaces:

- the `ns` form's `:require`, `:use` and `:import` clauses — an imported deftype or
  defrecord class names the namespace that defines it;
- every fully-qualified symbol under a `quote` in code.  These are the edges no `ns`
  form states: the `requiring-resolve` targets and the fixed symbol tables that name
  them (`vaelii.core`'s calculi, reasoners and solvers, `vaelii.impl.imperative`'s `do/`
  handlers, `vaelii.impl.wiring`'s three entry points).

The walk follows `vaelii.core` and `vaelii.impl.*` and nothing else.  Code from outside
those prefixes — a registered prover or evaluatable, a foreign plugin — is not in the
digest; `vaelii.impl.belief-image` refuses to write or install an image for a KB that
runs any.

## What is hashed

Each file is read as forms, and the forms are hashed with four things removed: comments,
`(comment …)` blocks, docstrings, and the reader's position metadata.  An edit that
changes only prose therefore leaves the digest unchanged.  An edit to code, or to
metadata the compiler reads (`^:dynamic`, `^:const`, a type hint), changes it.

The reader mints a fresh name on every read for two kinds of symbol: a syntax-quote
auto-gensym (`x#`) and an anonymous-fn argument (`%`).  Both are renumbered in order of
first appearance within their top-level form, so two reads of one file hash alike.
Aliases, classes and vars are read through a `*reader-resolver*` that resolves each to
itself, so a file reads the same way whether or not its namespace is loaded.

## A namespace with no source

The Clojars jar, the uberjar and a source checkout all carry the `.clj` files, so every
namespace is normally read as forms.  A namespace on the classpath only as compiled
classes contributes the digest of the code it loads from instead: the whole jar its
`__init` class sits in, or every class file of the namespace in a class directory.  A
namespace compiles to one class per fn, so no single class file covers its code.  The
jar digest changes with any rebuild, which is conservative: an image is discarded more
often, never installed under different code.

## Libraries

Each third-party library the closure requires or imports contributes the file name of
the jar its code loads from (`nippy-3.5.0.jar`), and the file name carries the version.
A library loaded from a directory rather than a jar contributes its namespace or class
name.  JDK classes contribute nothing.

Nothing here memoizes: a REPL can change a source file between two calls, and the
digest describes the files as they stand at the call.
raw docstring

closureclj

(closure)

The sorted set of namespaces whose source the digest covers.

The sorted set of namespaces whose source the digest covers.
sourceraw docstring

forms-digestclj

(forms-digest text)

The hex digest of the source text with its comments, docstrings and reader positions removed.

The hex digest of the source `text` with its comments, docstrings and reader positions
removed.
sourceraw docstring

read-formsclj

(read-forms text)

The top-level forms of the source text, without (comment …) blocks. Reads with *read-eval* off and the self-resolving *reader-resolver*.

The top-level forms of the source `text`, without `(comment …)` blocks.  Reads with
`*read-eval*` off and the self-resolving `*reader-resolver*`.
sourceraw docstring

rootsclj

The namespaces the closure starts from: recovery, which derives belief on open, and the public API, whose write entry points derive it between opens.

The namespaces the closure starts from: recovery, which derives belief on open, and the
public API, whose write entry points derive it between opens.
sourceraw docstring

source-identityclj

(source-identity)

{:digest hex :namespaces n :libraries [jar …]} for the source on the classpath now. :digest covers the forms of every namespace in closure, each under its name, and the sorted library names.

`{:digest hex :namespaces n :libraries [jar …]}` for the source on the classpath now.
`:digest` covers the forms of every namespace in `closure`, each under its name, and the
sorted library names.
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