Core interfaces
The contracts every other family is built on: copying, equality, ordering, hashing, iteration, views, and reading and writing text.
Generated by
bin/build_library_doc.pyfrom the kernel sources. Do not edit by hand: change the generator, or the doc comments inkernel/src/, and re-run it.
Collections and iteration
INTERFACE BidirectionalIterator
BidirectionalIterator OF T — extends ReferenceIterator OF T with reverse traversal. Used by Array, LinkedList, SortedList, Deque per spec L763-768.
- hasPrevious() — TRUE if cursor has not reached the start
- previous() — moves cursor backward, returns the element; STATUS = FAILURE at start
- skipBack(n) — moves cursor backward by n positions; returns the element at the new position, or STATUS = FAILURE if start is reached. Symmetric to skip(n). skipBack(0) is equivalent to peek().
kernel/src/interfaces.ev:429
Methods
METHOD hasPrevious() RETURNS boolean
MODIFY METHOD previous() RETURNS | REFERENCE T
MODIFY METHOD skipBack(uint64 n) RETURNS | REFERENCE T
GROUP Collectable
kernel/src/interfaces.ev:145
INTERFACE Collection
The minimum definition of a Collection container — what every container in the standard library can answer, so that membership of this interface is what marks a type AS a collection.
3 METHODS: iterator() declared here size() and isEmpty() inherited from Countable
contains() is deliberately NOT here, and the reason is the whole shape of
the interface. Containment needs EQUALITY on T, and Array[T] requires only
Cloneable of its elements — so putting contains in the minimum would force
Equatable onto every element type in the language the moment Array joined.
That is the split the industry already divides on: where equality is
UNIVERSAL (Java's Object.equals, Python's eq) a Collection can require
contains, and where equality is OPT-IN (Rust, Swift, C++) it cannot —
Swift's Collection requires iteration and offers contains only as an
extension where Element: Equatable. Envzn is the second kind. Containment
belongs with Searchable OF T, whose find needs exactly the same equality
and of which contains is the boolean shadow.
ITERATION is also the more primitive notion: contains is DERIVABLE from
iterating and comparing, while iteration cannot be derived from containment.
A minimum should be the irreducible core.
The qualifier is deliberately the WIDEST of any container's: iterator(),
size() and isEmpty() ask NOTHING of T, so nothing here should either.
Shareable is listed beside Cloneable because the OwnedList family
constrains its element that way, and refusing it would exclude a container
from the interface over a contract the interface never uses.
kernel/src/interfaces.ev:492
Methods
METHOD iterator() RETURNS ReferenceIterator[T]
GROUP Collectors
kernel/src/interfaces.ev:133
INTERFACE Countable
Countable is an opt-in interface for any class that enumerates how many elements it holds.
kernel/src/interfaces.ev:221
Methods
METHOD size() RETURNS int64
METHOD isEmpty() RETURNS boolean
INTERFACE Iterator
Iterator OF T — forward-traversal cursor over a collection. Per spec §Iterator (L730+).
- hasNext() — TRUE if cursor has not reached the end
- next() — advances cursor and returns the new element; EMPTY when end is reached
- peek() — returns what next() would return, without advancing. Calling twice in a row returns the same value
- skip(n) — moves cursor forward by n positions; returns
the element at the new position, or EMPTY if end
is reached. skip(0) is equivalent to peek().
Parameter is unsigned: backward movement is
unavailable on Iterator OF T (forward-only
iterators have no notion of "previous"). Use
BidirectionalIterator OF T's skipBack(n) for
reverse traversal.
Iterator OF T — the iteration root. The only operation universal
to every iterator is hasNext(): no single advance form fits both
referenceable storage and by-value storage, so the advance methods
live on the two sub-interfaces below. The FOR / WHILE loop
machinery holds an Iterator and dispatches on which sub-interface
the concrete iterator implements — ReferenceIterator (collections,
referenceable storage) or ValueIterator (buffers, by-value storage).
The element is what is ITERATED, and
hasNext()uses it not at all — the qualifier saidT IS Countable, which asked the ELEMENT to have a size.
kernel/src/interfaces.ev:255
Methods
METHOD hasNext() RETURNS boolean
INTERFACE ObjectIterator
ObjectIterator OF T — extends Iterator with by-reference navigation
over a HEAP-CLASS element type. The object peer of ReferenceIterator:
where ReferenceIterator's bound admits only Cloneable primitives,
ObjectIterator admits any class, so a collection whose logical
element is a synthesized class instance (a per-position VIEW — e.g.
a DataFrame yielding a Row built from its stored columns) can be
FOR e IN coll-iterable. Because the source may not STORE the
element (it synthesizes it), the concrete iterator OWNS the current
element in an internal slot and hands back a non-owning REFERENCE
into that slot; the reference is valid until the next advance, on
which the slot is refreshed. The FOR-IN loop borrows it for the
iteration exactly as it borrows a ReferenceIterator's referent —
so next() lowers to REFERENCE T (a T*) on both this interface
and its implementers, with none of the value-form covariance seam.
kernel/src/interfaces.ev:405
Methods
MODIFY METHOD next() RETURNS | REFERENCE T
2.0 pipe-XOR shape: a successful navigation refreshes the
iterator's owned slot and populates value with a non-owning
reference into it; end-of-iteration populates s with FAILURE.
METHOD peek() RETURNS | REFERENCE T
peek is non-consuming: the reference to the current slot without advancing. Same pipe-XOR shape as next().
INTERFACE ReferenceIterator
ReferenceIterator OF T — extends Iterator with by-reference
navigation. Implemented by the collection iterators, whose backing
storage is referenceable: next() / peek() / skip() hand back a
non-owning reference into the source rather than a copy. Buffer
iterators (over by-value _cxx* storage) implement only the
value-form Iterator.
next/peek/skip hand back a REFERENCE and never clone, so Cloneable
was never used; Shareable joins it so the OwnedList family qualifies.
kernel/src/interfaces.ev:355
Methods
MODIFY METHOD next() RETURNS | REFERENCE T
2.0 pipe-XOR shape: a successful navigation populates value
with a non-owning reference into the source; end-of-iteration
or invariant violation populates s with FAILURE. The caller's
IF iter->next() THEN { use($RETURNED) } ELSE { ... } consumes the
populated slot.
METHOD peek() RETURNS | REFERENCE T
peek is non-throwing and non-consuming: returns the reference at the current cursor without advancing. Same pipe-XOR shape as next().
MODIFY METHOD skip(uint64 n) RETURNS | REFERENCE T
INTERFACE Searchable
Searchable OF T — contents can be searched for a needle of the same
Text kind. find returns the match position; pipe-XOR FAILURE means
no match. Implemented by String and StringView — the view holds the
one canonical scan, and String forwards through a full-span view.
kernel/src/interfaces.ev:292
Methods
METHOD find(REFERENCE T needle) RETURNS | int64
INTERFACE ValueIterator
ValueIterator OF T — extends Iterator OF T with by-value navigation. Implemented by the buffer iterators, whose backing storage yields elements by value, not by reference: nextValue() / peekValue() / skipValue() hand back a copy of the element. The value-form mirror of ReferenceIterator.
kernel/src/interfaces.ev:377
Methods
MODIFY METHOD nextValue() RETURNS | T
2.0 pipe-XOR shape: a successful navigation populates value
with a copy of the element at the new cursor; end-of-iteration
populates s with FAILURE.
METHOD peekValue() RETURNS | T
peekValue is non-consuming: the value at the current cursor without advancing. Same pipe-XOR shape as nextValue().
MODIFY METHOD skipValue(uint64 n) RETURNS | T
Copying and ownership
INTERFACE Cloneable
Cloneable — per Bug #23. A class implementing Cloneable opts in
to deep-copy semantics: := on instances calls clone(); the
*Copy family of collection methods clones each class-typed
element through this interface.
Implementations declare their own concrete return type — Envzn's interface satisfaction rule accepts any return type that itself implements Cloneable (covariant-return-via-subtype), so:
CLASS Person IMPLEMENTS Cloneable { METHOD clone() RETURNS Person { Person p := CREATE Person(.age) RETURN (p) } }
...satisfies the contract without any cast.
An AUTO clone is the other form, and it declares NO return type: the
compiler supplies the body AND the concrete return type, so writing
RETURNS on one is E7029 (auto-clone-with-returns).
CLASS Point IMPLEMENTS Cloneable {
AUTO METHOD clone() { } // generated; never RETURNS Point
}
kernel/src/interfaces.ev:175
Methods
METHOD clone() RETURNS Cloneable
INTERFACE Inoperative
Inoperative — marker for types whose values can't be operated on
in generic code. Today's sole member is the Part-G opaque
primitive: type-erased payload whose static type is opaque to
callers, so no method dispatch is well-defined. Generic kernel
containers (Array, Dictionary, Set, etc.) use
WHEN T IMPLEMENTS Inoperative { /* no-op stub */ } ELSE { ... }
to opt out of clone, copy, and iteration paths that would
instantiate to deleted-ctor / dangling-handle errors for opaque.
The inoperativeReason() method is the sole operation valid on an
Inoperative value — it returns a fixed-text human-readable
description of why this type is opaque. Used by debug printers,
error formatters, and kernel logs that need to render "what is
this thing I got" without unwrapping.
Compile-time WHEN T IMPLEMENTS Inoperative lowers to a special
_is_inoperative_v<T> trait check (see EV_handles.hpp)
rather than the usual std::is_base_of_v<> path, because
opaque is a runtime struct (not a class that can inherit from
an interface). The dispatch of inoperativeReason() itself is
hardcoded in the emitter for the opaque keyword type.
kernel/src/interfaces.ev:339
Methods
METHOD inoperativeReason() RETURNS String
Equality, ordering and hashing
INTERFACE Comparable
Comparable[T] — type defines a strict less-than ordering. Extends Equatable[T]: a type that is comparable is necessarily equatable (otherwise sorted-and-equal-to checks can't compose).
Required for any T used in:
- SortedList[T] (insert position determined by isLessThan)
- Array[T]->sort() (insertion-sort or quicksort comparator)
- any future ordered collection
The implementation MUST satisfy a strict total order:
- Irreflexive — a.isLessThan(a) is always FALSE.
- Antisymmetric — if a.isLessThan(b) then NOT b.isLessThan(a).
- Transitive — if a.isLessThan(b) and b.isLessThan(c),
then a.isLessThan(c).
- Trichotomous (consistent with Equatable) — for every
pair, exactly one of a.isLessThan(b), b.isLessThan(a),
or a.isEqualTo(b) is TRUE.
The kernel provides built-in Comparable behaviour for primitive
numerics (int8..int64, uint8..uint64, float32, float64,
byte, char) and String (lexicographic). boolean is also
comparable (FALSE < TRUE). Class types must declare
IMPLEMENTS Comparable[K] and provide isLessThan(K) and
isEqualTo(K) methods explicitly.
isLessThanOrEqual, isGreaterThan, isGreaterThanOrEqual are
derivable and not part of this interface; the canonical method
is isLessThan. Callers compose: NOT a.isLessThan(b) is
"a >= b", b.isLessThan(a) is "a > b", etc.
kernel/src/interfaces.ev:528
Methods
METHOD isLessThan(REFERENCE T other) RETURNS boolean
INTERFACE Equatable
Equatable[T] — type can compare itself to another instance of the same type for value equality. Parameterised over T to pin the comparison type at the implementation site:
CLASS Token IMPLEMENTS Equatable[Token] {
METHOD isEqualTo(Token other) RETURNS boolean { ... }
}
Equatable is the contract Dictionary uses to resolve hash collisions and Set uses for membership. Required alongside Hashable for any class type used as a Dictionary key.
Implementations must be:
- Reflexive — a.isEqualTo(a) is always TRUE.
- Symmetric — a.isEqualTo(b) iff b.isEqualTo(a).
- Transitive — if a.isEqualTo(b) and b.isEqualTo(c),
then a.isEqualTo(c).
- Consistent with Hashable — if a.isEqualTo(b), then
a.hash() == b.hash(). (The reverse need not hold; hash
collisions on equal-by-isEqualTo objects break Dictionary.)
Built-in for primitives and String, same as Hashable.
kernel/src/interfaces.ev:283
Methods
METHOD equals(REFERENCE T other) RETURNS boolean
GROUP HashKey
kernel/src/interfaces.ev:128
INTERFACE Hashable
Hashable — type can produce a stable hash code of itself.
Returned value is uint64 per spec §Hashable and KeyHasher
(CONSTITUTION L3611). Implementing classes are eligible for use
as Dictionary[K: V] keys (paired with Equatable[K], below) and
Set[T] elements.
The hash MUST be: - Deterministic — equal objects (per Equatable.isEqualTo) must produce equal hashes. Calling hash() on the same value twice must yield the same result. - Pure — no observable side effects, no I/O, no mutation of SELF or any reachable state.
The kernel provides built-in Hashable behaviour for primitives
(int8..int64, uint8..uint64, float32, float64, byte,
char, boolean) and String — those types do not need to
declare IMPLEMENTS Hashable explicitly. Dictionary[K: V] uses
the built-in path automatically when K is one of those.
kernel/src/interfaces.ev:455
Methods
METHOD hash() RETURNS uint64
GROUP WordKey
GROUP WordKey — a primitive whose value IS an integer bit-pattern, so a
hasher body may reduce it to its hash word with uint64 v = #key (I.F.ii(a):
the value mod 2^64) and nothing about the value domain changes. It is
exactly the operand set # accepts (E2153).
FastIntHasher and InlineIntHasher were qualified PRIMITIVE(EXCEPT
opaque, boolean, number, complex) while their bodies are a bare
uint64 v = key — which TRUNCATES for float32/float64, is forbidden outright
for decimal128 (E2121 — decimal never mixes), and names a FOREIGN-only type
for the C.* four. The constraint admitted types the body could not honour.
This is the set it can.
int128/uint128 ARE members, and they are the one case where the reduction is
lossy: the high 64 bits are dropped, so two keys differing only above bit 63
hash alike. That is a WEAK hash, not a wrong one — Equatable still
separates them on lookup, and taking low bits is an ordinary hash fold. A
float is excluded for the different reason that its bits are not a value:
the same number has several encodings, so # on it would not be a fold but
a reinterpretation. (Brian, 2026-08-24.)
kernel/src/interfaces.ev:107
Text I/O
INTERFACE Printable
Printable — type can render itself directly to stdout.
Distinct from Readable — Readable produces a String for the caller to do something with; Printable is the convenience for types that own their own output side effects (e.g. a complex renderer that writes structured output to multiple lines).
Most types should implement Readable and let callers route the output. Printable is for cases where producing the intermediate String would be wasteful (e.g. large structured dumps).
kernel/src/interfaces.ev:615
Methods
METHOD print() RETURNS void
INTERFACE Readable
Readable — a byte source: the counterpart of Writable. The single
operation is read — drain the source into an storage char8[512+]
of whatever it had. File, Socket, and the Stdio stdin source
implement it, so code can ask of any of them "can I read this?"
the same way Writable answers "can I write it?".
read returns the bytes it managed to produce as a char8[512+]
storage value — empty when the source has none, populated through
to end-of-input otherwise. The FAILURE status is reserved for a
genuine read error, not for a short or empty read. The caller can
build a ByteBuffer or DynamicByteBuffer from the returned
storage when a wrapper is needed (§21).
Spec reference: stdio-spec.md §6.
kernel/src/interfaces.ev:598
Methods
MODIFY METHOD read() RETURNS | binary[]
GROUP Text
kernel/src/interfaces.ev:137
INTERFACE Writable
Writable — a byte sink. The single operation is write: hand it a
ByteBuffer and it delivers every byte or fails. Implemented by the
Stdio stdout/stderr sinks, by File, and by Socket — so a rendered
String (from a Formatter) can reach any of them through one
uniform call.
All-or-nothing: a short OS write is retried internally, so the outcome is SUCCESS — every byte written, count returned — or a FAILURE status. There is no partial write.
THE EXTENT IS THE ARRAY'S OWN LENGTH — there is deliberately no
length parameter (gh #195, removed 2026-08-12). The old shape
write(content, length) passed the caller's integer straight to
POSIX write, which reads that many bytes from the base pointer:
write(twoByteBuffer, 65536) wrote 64 KB of live heap — including a
pointer — to disk, with no diagnostic at any phase. CWE-126, and
severity 10 against I.A's memory-safe floor.
It was also redundant. read/readAt already return a char8[]
whose .length IS the valid extent, so the class conveyed extent by
array length in one direction and by a separate integer in the other.
Three of the four call sites in the whole corpus passed a value equal
to the array's length anyway.
To write PART of a buffer, take a view (ByteBufferView is
REFERENCE char8[] source + start + length) or pass a right-sized
array. A lone length could only ever express a prefix — it has no
offset — so it was never the right tool for a slice.
Spec reference: stdio-spec.md §6.
kernel/src/interfaces.ev:747
Methods
MODIFY METHOD write(REFERENCE binary[] content) RETURNS | int64
Views
INTERFACE View
View — the non-owning window itself. Minimal base contract; the element-typed operations (operator[], iterator, find via Searchable, copy) live on the concrete view (StringView). Kept deliberately minimal so a future N-D view tier is not constrained by 1-D shape. Declared before Viewable because Viewable.view() references it.
kernel/src/interfaces.ev:301
Methods
METHOD length() RETURNS int64
INTERFACE Viewable
Viewable — a source that yields a non-owning, bounded View into its
own storage without copying. view(start, length) windows over
[start, start+length). The return type is the base View; an
implementer narrows it covariantly to its concrete view (String
returns StringView). This is the 1-D / linear tier (String now;
ArrayView / byte-buffer views later) — the N-D strided views the
Data module needs are a separate, related contract.
kernel/src/interfaces.ev:312
Methods
METHOD view(int64 start, int64 length) RETURNS View