cljrs-value
Core runtime values and persistent collections for clojurust.
Phase: 3 (collections/Value) + 4 (CljxFn, Namespace) + 5 (LazySeq, CljxCons) + 6 (Protocol, ProtocolFn, MultiFn) + 7 (Volatile, Delay, CljxPromise, CljxFuture, Agent) + 6-ext (TypeInstance for defrecord/reify) — implemented.
Purpose
Defines Value, the single enum that represents every Clojure runtime value,
plus all persistent (immutable, structurally shared) collection types. The
cljrs-eval crate will operate on Values; cljrs-runtime will build the
standard library on top of them.
File layout
src/
lib.rs — module declarations and re-exports
error.rs — ValueError enum, ValueResult<T> alias
hash.rs — ClojureHash trait, Murmur3 helpers, JVM-compatible hash_string
keyword.rs — Keyword { namespace, name }
symbol.rs — Symbol { namespace, name }
native_object.rs — NativeObject trait, NativeObjectBox wrapper, gc_native_object helper (Phase 9 interop)
types.rs — Var, Atom, Namespace, NativeFn, CljxFn, Thunk, LazySeq, CljxCons, Protocol, ProtocolFn, ProtocolMethod, MultiFn, Volatile, Delay, CljxPromise, CljxFuture, Agent
value.rs — Value enum (incl. NativeObject variant), MapValue, TypeInstance, pr_str, PartialEq, ClojureHash, std::hash::Hash
collections/
mod.rs — re-exports all collection types
array_map.rs — PersistentArrayMap (≤8 entries, linear scan)
hash_map.rs — PersistentHashMap (32-way HAMT)
hash_set.rs — PersistentHashSet (backed by PersistentHashMap)
list.rs — PersistentList (singly-linked cons list)
queue.rs — PersistentQueue (front-list + rear-vector)
vector.rs — PersistentVector (32-way trie + tail buffer)
hamt/
mod.rs — re-exports Node and bitmap helpers
bitmap.rs — BITS, WIDTH, fragment, sparse_index, bit_for
node.rs — Node<V> enum (Leaf, Branch, Collision); HAMT trie operations
Public API
Value
PartialEq implements cross-type numeric equality ((= 1 1N), (= 1 1.0))
and sequential collection equality between List and Vector.
Display / pr_str produce Clojure-readable output.
Symbol / Keyword
Both support simple(name), qualified(ns, name), parse(str), and
full_name() -> String.
ClojureHash
Implemented for Value using Murmur3 + JVM String.hashCode semantics.
Whole-number doubles hash like their Long equivalent.
Collections
| Type | Description | Key operations |
|---|---|---|
PersistentList |
Singly-linked cons list | cons, first, rest, count (O(1)) |
PersistentVector |
32-way trie + tail buffer | conj, nth, assoc_nth, pop, iter |
PersistentArrayMap |
Flat key/value vec, ≤8 entries | assoc (returns AssocResult), get, dissoc, iter |
PersistentHashMap |
32-way HAMT | assoc, get, dissoc, merge, iter, keys, vals |
PersistentHashSet |
Backed by PersistentHashMap |
conj, disj, contains, iter |
PersistentQueue |
Front-list + rear-vector | enqueue, dequeue, peek |
PersistentArrayMap::assoc returns AssocResult::Array(Self) while under the
threshold, or AssocResult::Promote(Vec<(Value, Value)>) when the map is full.
MapValue::assoc handles the transparent promotion to PersistentHashMap.
All collections implement PartialEq, Debug, Clone, and cljrs_gc::Trace.
PersistentList, PersistentVector, and PersistentHashSet implement
std::iter::FromIterator<Value>.
CljxFn / CljxFnArity (Phase 4)
// Requires cljrs-reader (for Vec<Form> body).
Namespace (Phase 4)
Thunk / LazySeq / CljxCons (Phase 5)
Thunk implementations live in cljrs-eval (e.g. ClosureThunk) so that
cljrs-value stays free of evaluator dependencies while LazySeq can still
call back through the trait object.
TypeInstance (Phase 6-ext — defrecord/reify)
Used by defrecord (named type_tag, generates ->Name/map->Name constructors) and
reify (gensym'd type_tag, no constructors). Supports keyword field access (:field rec),
get, assoc (returns new TypeInstance), and count.
Volatile / Delay / CljxPromise / CljxFuture / Agent (Phase 7)
// Pending(Box<dyn Thunk>) | Forced(Value)
pub type AgentFn = ;
Protocol / ProtocolFn / MultiFn (Phase 6)
Dependencies
cljrs-value depends on cljrs-reader so that CljxFnArity::body can store
Vec<Form> (unevaluated source bodies for interpreter evaluation and closure
capture).