Skip to main content

core::base — Foundational types and protocols

Everything in core::base is loaded by the prelude — you do not need to mount it. It contains the types and protocols that every other module assumes.

This page enumerates every public item.

FileWhat's in it
maybe.vrMaybe<T>, MaybeIter<T>, collect_maybe, flatten_maybe
result.vrResult<T,E>, ResultIter<T>, Error
ordering.vrOrdering
ops.vrControlFlow<B,C>, Try, FromResidual, Never, Drop
protocols.vrthe operator and capability protocols (Eq, Ord, Hash, Clone, Copy, Default, Debug, Display, Send, Sync, Add..Shr, From/Into, Deref/AsRef, Numeric, …)
iterator.vrIterator protocol + 30+ adapters
cell.vrCell, RefCell, OnceCell, LazyCell, Ref, RefMut
memory.vrHeap<T>, Shared<T>, Weak<T>, Cow<T>, Pin<P>, ManuallyDrop<T>, MaybeUninit<T>
panic.vrpanic, assert, unreachable, todo, catch_unwind, PanicInfo
env.vrargs, var, home_dir, os_name, arch, exit
data.vrData (dynamic JSON-like value), parse_json
serde.vrSerialize, Deserialize, Serializer, Deserializer
error.vrStackFrame, Backtrace, ErrorProtocol, ErrorChain
log.vrLogLevel, Logger, LogRecord, trace/debug/info/warn/error
coinductive.vrcorecursive analysis (CorecursiveCall, check_productivity, bisimilar_up_to)
primitives.vrinherent methods on Int, Float, Bool, Char, Byte

Maybe<T> — optional value

type Maybe<T> is None | Some(T);

The Verum equivalent of Option. Used wherever a value may be absent.

Constructing

let a: Maybe<Int> = Maybe.Some(42);
let b: Maybe<Int> = Maybe.None;

let parsed = "42".parse_int(); // returns Maybe<Int>

Inspecting

m.is_some() -> Bool
m.is_none() -> Bool
m.contains(&value) -> Bool // requires T: Eq
m.is_some_and(f: fn(&T) -> Bool) -> Bool
m.is_none_or(f: fn(&T) -> Bool) -> Bool

Unwrapping

m.unwrap() // panics if None
m.expect("must exist") // panics with message
m.unwrap_or(default)
m.unwrap_or_else(|| compute())
m.unwrap_or_default() // requires T: Default

Transforming

m.map(|x| x + 1) // Maybe<U>
m.and_then(|x| if x > 0 { Some(x) } else { None })
m.or_else(|| compute_fallback())
m.map_or(default, |x| x + 1)
m.map_or_else(|| default(), |x| x + 1)
m.filter(|x| *x > 0)
m.flatten() // Maybe<Maybe<T>> -> Maybe<T> (T: Default)

Combining

m.and(other) // Maybe<U>: Some(_).and(x) = x; None.and(_) = None
m.or(other) // Maybe<T>: Some(x).or(_) = Some(x); None.or(y) = y
m.xor(other) // exclusive: Some/None or None/Some
m.zip(other) // Maybe<(T, U)>
m.zip_with(other, |a, b| a + b)

Result interop

m.ok_or(error) // Maybe<T> -> Result<T, E>
m.ok_or_else(|| make_error())

Mutating

m.take() // -> Maybe<T>, leaves *self = None
m.replace(value) // -> Maybe<T>, sets *self = Some(value)
m.insert(value) // -> &mut T
m.get_or_insert(value) // -> &mut T
m.get_or_insert_with(|| compute())
m.get_or_insert_default() // T: Default
m.take_if(|x| should_take(x))

Iteration

for x in m.iter() { ... } // 0 or 1 element
for x in m.iter_mut() { ... }

Module-level helpers

collect_maybe(iter) // Iterator<Maybe<T>> -> Maybe<List<T>> (all-or-nothing)
flatten_maybe(items) // &List<Maybe<T>> -> List<T> (skip None)
flatten_maybe_iter(iter) // Iterator<Maybe<T>> -> List<T>

? operator

? propagates None from a Maybe-returning function:

fn first_word(text: &Text) -> Maybe<Text> {
let space = text.find(" ")?; // returns None early
Maybe.Some(text.slice(0, space))
}

Pitfall — accidental swallowing

m.unwrap_or(default) discards the information that the value was absent. When the absence might indicate a bug, prefer expect (with a precise message) so the panic carries diagnostic value.


Result<T, E> — fallible value

type Result<T, E> is Ok(T) | Err(E);

The canonical error type. By convention E is a dedicated error enum (type ParseError is …) or, for quick code, Text.

Constructing

let r: Result<Int, Text> = Result.Ok(42);
let r: Result<Int, Text> = Result.Err("bad");

Inspecting

r.is_ok() -> Bool
r.is_err() -> Bool
r.is_ok_and(|v| *v > 0)
r.is_err_and(|e| matches(e, Error.Timeout))

Conversion

r.ok() // Result<T,E> -> Maybe<T>
r.err() // Result<T,E> -> Maybe<E>

Unwrapping

r.unwrap() // E: Debug; panics on Err
r.unwrap_err() // T: Debug; panics on Ok
r.expect("must succeed")
r.expect_err("must fail")
r.unwrap_or(default)
r.unwrap_or_else(|e| recover(e))
r.unwrap_or_default() // T: Default

Transforming

r.map(|t| t + 1) // Result<U,E>
r.map_err(|e| ApiError::wrap(e)) // Result<T,F>
r.map_or(default, |t| t + 1)
r.map_or_else(|e| handle_err(e), |t| t + 1)
r.and_then(|t| further(t)) // flatmap on Ok
r.or_else(|e| recover(e)) // flatmap on Err
r.and(other) // (Ok(_), x) -> x; (Err(e), _) -> Err(e)
r.or(other)
r.flatten() // Result<Result<T,E>,E> -> Result<T,E>

Borrowing & inspection

r.as_ref() // Result<T,E> -> Result<&T, &E>
r.as_mut() // -> Result<&mut T, &mut E>
r.inspect(|t| log(t)) // pass-through with side effect on Ok
r.inspect_err(|e| log(e)) // pass-through with side effect on Err

Iteration

for v in r.iter() { ... } // 0 elements on Err, 1 on Ok
for v in r.iter_mut() { ... }

Error (lightweight catch-all)

type Error is { message: Text };
let e = Error.new("something broke");

Implements Debug + Display + Describable + Eq + Clone. Useful when you do not yet have a typed error hierarchy. Replace with a dedicated error enum (type MyError is | NotFound | Timeout(Duration)) once the failure modes stabilise.

? operator

In a function returning Result<_, E>, the ? operator unwraps an Ok or returns the Err early — converting via From if necessary.

fn load_config() -> Result<Config, Error> {
let bytes = fs::read("config.toml")?;
let text = Text.from_utf8(&bytes)?;
toml::parse(&text)
}

Pitfall — unwrap in libraries

unwrap is fine in tests and prototypes. In library code, prefer ? and let the caller decide. expect("invariant: …") is acceptable when you can articulate why panic is the only sane response.


Ordering

type Ordering is Less | Equal | Greater;

The result of cmp. Total ordering primitives.

o.is_less() / o.is_equal() / o.is_greater()
o.is_le() / o.is_ge()
o.reverse() // Less <-> Greater
o.then(other) // lexicographic chain
o.then_with(|| compute()) // lazy chain
o.to_int() // -1 / 0 / 1
Ordering.from_int(n) // parse from -1/0/1

Lexicographic comparison idiom:

fn cmp(a: &Person, b: &Person) -> Ordering {
a.last.cmp(&b.last)
.then_with(|| a.first.cmp(&b.first))
.then_with(|| a.age.cmp(&b.age))
}

ControlFlow<B, C> and Try

type ControlFlow<B, C> is Continue(C) | Break(B);

The protocol behind ?. You rarely write it directly, but it powers custom early-return types:

type Try is protocol {
type Output;
type Residual;
fn from_output(output: Output) -> Self;
fn branch(self) -> ControlFlow<Residual, Output>;
};

type FromResidual<R> is protocol {
fn from_residual(residual: R) -> Self;
};

Maybe, Result, and any user-defined sum type can implement Try to participate in the ? operator.

Never (alias !) is the bottom type; it can be coerced to any type. Returned by panic, exit, infinite loops, etc.


Operator protocols

Implementing these makes your type work with the corresponding syntax. From protocols.vr:

ProtocolSyntaxMethods
PartialEq==, !=eq(&self, other: &Self) -> Bool
Eq(marker)extends PartialEq
PartialOrd<, <=, >, >=partial_cmp(&self, other: &Self) -> Maybe<Ordering>
Ord(sortable)cmp(&self, other: &Self) -> Ordering; min, max, clamp
Hashhashinghash<H: Hasher>(&self, h: &mut H)
Clone.clone()clone(&self) -> Self, clone_from(&mut self, other: &Self)
Copyimplicit copyextends Clone; marker only
DefaultT.default()default() -> Self
Debug{:?}fmt_debug(&self, f: &mut Formatter) -> FmtResult
Display{}fmt(&self, f: &mut Formatter) -> FmtResult
Dropscope exitdrop(&mut self)
Add<Rhs>a + badd(self, rhs: Rhs) -> Self.Output
Sub, Mul, Div, Rem, Negarithmeticanalogous
BitAnd, BitOr, BitXor, Not, Shl, Shrbitwiseanalogous
AddAssign..ShrAssigna += b etc.in-place compound
Index<Idx>xs[i]index(&self, i: Idx) -> &Self.Output
IndexMut<Idx>xs[i] = …index_mut(&mut self, i: Idx) -> &mut Self.Output
Derefauto-derefderef(&self) -> &Self.Target
DerefMutmutable auto-derefderef_mut(&mut self) -> &mut Self.Target
From<T>T.from(x)from(x: T) -> Self
Into<T>x.into()into(self) -> T
TryFrom<T> / TryInto<T>fallible variantswith Error associated type
AsRef<T>&Self -> &Tas_ref(&self) -> &T
AsMut<T>&mut Self -> &mut Tas_mut(&mut self) -> &mut T
Borrow<B> / BorrowMut<B>hash-key borrowingborrow(&self) -> &B

Numeric protocols

type Zero is protocol { fn zero() -> Self; fn is_zero(&self) -> Bool; }
type One is protocol { fn one() -> Self; fn is_one(&self) -> Bool; }
type Numeric is protocol; // implemented by all primitive numerics
type SignedNumeric is protocol extends Numeric;
type Integer is protocol extends Atomic;
type SignedInteger is protocol extends Integer;
type Atomic is protocol; // safe for atomic ops

Capability protocols

type Sized is protocol; // statically sized; auto for almost all types
type Send is protocol; // safe to move across threads
type Sync is protocol; // safe to share `&Self` across threads
type Unpin is protocol; // not structurally pinned
type Any is protocol { fn type_id(&self) -> TypeId; }

Send and Sync are auto-derived; opt out with !Send / !Sync in generic bounds (fn f<T: Send + !Sync>(x: T)).

Error protocols

type Describable is protocol { fn description(&self) -> Text; }
type ErrorSource is protocol extends Describable {
fn source(&self) -> Maybe<&dyn ErrorSource>;
}
type ErrorProtocol is protocol extends ErrorSource {
fn message(&self) -> Text;
fn backtrace(&self) -> Maybe<&Backtrace>;
}
type FromStr is protocol { fn from_str(s: &Text) -> Result<Self, ParseError>; }
type ToString is protocol { fn to_string(&self) -> Text; }

Implementations the stdlib provides

TraitFor
Numericevery primitive integer + every Float*
Integerevery primitive integer
SignedIntegerInt8..Int128, Int, ISize
Atomicevery primitive integer + Bool
HasherDefaultHasher (FxHash-based, wrapping_mul core)

Iterator and adapters

type Iterator is protocol {
type Item;
fn next(&mut self) -> Maybe<Self.Item>;
fn size_hint(&self) -> (Int, Maybe<Int>);
// ... 60+ default methods
}

Consuming methods (terminal)

.count() // -> Int
.last() // -> Maybe<Item>
.nth(n) // -> Maybe<Item>
.advance_by(n) // -> Result<(), Int>
.collect::<C>() // -> any C: FromIterator<Item>
.fold(init, |acc, x| ...) // -> B
.reduce(|a, b| max(a,b)) // -> Maybe<Item>
.try_fold(init, |acc, x| ...)
.scan(state, |st, x| ...)
.all(|x| pred(x)) // -> Bool (short-circuits on false)
.any(|x| pred(x)) // -> Bool (short-circuits on true)
.find(|x| pred(x)) // -> Maybe<Item>
.find_map(|x| ...) // -> Maybe<U>
.position(|x| pred(x)) // -> Maybe<Int>
.sum() // -> Item: Add + Zero
.product() // -> Item: Mul + One
.min() / .max() // -> Maybe<Item> (Item: Ord)
.min_by_key(|x| key(x)) / .max_by_key
.min_by(|a,b| cmp) / .max_by
.min_max() // -> Maybe<(Item, Item)>

Adapter methods (lazy — return new iterators)

.map(|x| f(x)) // MappedIter
.filter(|x| pred(x)) // FilterIter
.filter_map(|x| ...) // FilterMapIter
.flat_map(|x| produce_seq(x)) // FlatMapIter
.flatten() // FlattenIter — Iter<Iter<T>> -> Iter<T>
.take(n) // TakeIter
.skip(n) // SkipIter
.take_while(|x| pred(x)) // TakeWhileIter
.skip_while(|x| pred(x)) // SkipWhileIter
.chain(other_iter) // ChainIter
.zip(other_iter) // ZipIter
.enumerate() // EnumerateIter — yields (Int, Item)
.peekable() // PeekableIter — adds .peek()
.dedup() // DedupIter — removes consecutive equals
.interleave(other_iter) // InterleaveIter
.step_by(stride) // StepByIter
.inspect(|x| log(x)) // InspectIter — pass-through with side effect
.fuse() // FuseIter — None stays None
.cycle() // CycleIter — repeats forever
.cloned() / .copied() // Iter<&T> -> Iter<T>
.chunks(n) // ChunksIter — windows of n
.windows(n) // WindowsIter — sliding window
.intersperse(separator) // IntersperseIter
.intersperse_with(|| sep()) // IntersperseWithIter
.pairwise() // PairwiseIter — yields (Item, Item)
.zip_longest(other) // ZipLongestIter
.map_while(|x| ...) // MapWhileIter — stops on None
.by_ref() // ByRef — iterate without consuming

Idiomatic chains

// sum of squares of odd numbers in 0..100
let s: Int = (0..100).filter(|x| x % 2 == 1).map(|x| x * x).sum();

// first prime > 1000
let p = (1001..).find(|n| is_prime(n));

// dedupe a sorted list and join with commas
let csv: Text = sorted.iter().dedup().map(|x| x.to_string())
.intersperse(",".to_string()).collect();

// produce a Map<Int, List<String>> grouped by length
let by_len: Map<Int, List<Text>> = words.iter()
.fold(Map.new(), |mut m, w| {
m.entry(w.len()).or_insert_with(List.new).push(w.clone());
m
});

Pitfall — re-using a consumed iterator

Iterators are single-use unless they implement Clone. Use .by_ref() when you want to consume only part of an iterator and keep iterating later.


Cells (interior mutability)

Cell<T> — copy-based, !Sync

let c = Cell.new(0);
c.set(42);
c.get(); // requires T: Clone
c.replace(100); // returns old value
c.take(); // returns value, leaves Default (T: Default)
c.update(|v| v + 1); // apply function in-place

RefCell<T> — runtime-borrow-checked, !Sync

let rc = RefCell.new(Vec.new());
{
let mut w = rc.borrow_mut(); // panics if any borrow active
w.push(1);
}
{
let r = rc.borrow(); // panics if mutable borrow active
print(f"{r.len()}");
}

// Non-panicking variants:
match rc.try_borrow_mut() {
Result.Ok(mut w) => { w.push(2); }
Result.Err(_) => log("contended"),
}

OnceCell<T> — write-once

let cfg: OnceCell<Config> = OnceCell.new();
cfg.set(load_config()).unwrap();
let value = cfg.get_or_init(|| load_config());

LazyCell<T> — lazy computation

let computed: LazyCell<HeavyResult> = LazyCell.new(|| compute_once());
let result = computed.force(); // computes on first call, caches

For thread-safe equivalents, see sync (AtomicCell, Mutex, RwLock, OnceLock).


Heap, Shared, Cow, Pin

TypeSemantics
Heap<T>unique heap allocation; CBGR-tracked
Shared<T>atomically ref-counted; Send + Sync if T: Send + Sync
Weak<T>non-owning ref to a Shared<T> (breaks cycles)
Cow<T>clone-on-write — borrowed &T until you call .to_mut()
Pin<P>structurally pinned (used for self-referential futures)
ManuallyDrop<T>wraps T to prevent automatic drop
MaybeUninit<T>wraps possibly-uninit memory; safe initialisation

Heap<T>

Heap.new(value) -> Heap<T> // panics on OOM
Heap.new_default() -> Heap<T> // T: Default
Heap.new_zeroed() -> Heap<T>
Heap.try_new(value) -> Result<Heap<T>, AllocError>

h.as_ref() / h.as_mut() // CBGR-checked deref
h.into_inner() -> T
h.into_raw() -> &unsafe T // leaks; pair with from_raw
Heap::from_raw(p) -> Heap<T> // unsafe
h.leak() -> &mut T

h.generation() / h.epoch() / h.is_valid() // CBGR introspection
h.is_allocated() / h.is_freed()
h.capabilities() // capability bits

Shared<T> and Weak<T>

Shared.new(value) Shared.clone(&s) s.weak() -> Weak<T>
weak.upgrade() -> Maybe<Shared<T>>
Shared.strong_count(&s) / weak_count

Cow<T>

let c: Cow<List<Int>> = Cow::Borrowed(&xs);
let owned: &mut List<Int> = c.to_mut(); // clones if Borrowed

Raw pointer helpers

ptr_read(p) ptr_write(p, value) // unsafe
drop_in_place(p) forget(value) // mem leaks
is_null(p) null_ptr::<T>()
ptr_offset(p, n)

For full memory primitives see mem.


panic and assertions

Panicking

panic("invariant violated") -> !
panic_at("oops", "src/foo.vr", 12, 4) -> !
abort() -> ! // immediate; no unwinding
exit(code) -> !

Assertions

assert(cond, "message")
assert_eq(left, right, "message") // T: Eq + Debug
assert_ne(left, right, "message")
assert_some(maybe, "expected Some")
assert_none(maybe, "expected None")
assert_ok(result, "expected Ok")
assert_err(result, "expected Err")

debug_assert(cond, "msg") // stripped in release
debug_assert_eq(a, b, "msg")
debug_assert_ne(a, b, "msg")

Markers

unreachable("dead branch") -> !
unreachable_unchecked("dead in release; UB hint") -> !
unimplemented("phase 2") -> !
todo("write me") -> !

Catch panics

catch_unwind(|| risky()) -> Result<T, PanicInfo>
resume_unwind(panic_info) -> !

Compile-time helpers

@file() @line() @column()
@function() @module()
@current_location()

PanicInfo carries message: Text, optional Location { file, line, column }. set_panic_handler(hook) installs a global hook (fn(&PanicInfo)).

dbg — print-and-pass-through

let total = dbg(items.iter().filter(|x| x.is_active()).count());
// stderr: [src/foo.vr:42] items.iter().filter(...).count() = 17

env — process environment

CLI arguments

args() -> List<Text> // all argv
arg(i) -> Maybe<Text>
args_count() -> Int
args_os() -> Args // iterator

Environment variables

var(key) -> Result<Text, VarError>
var_opt(key) -> Maybe<Text>
set_var(key, value)
remove_var(key)
vars() -> Vars // iterator over (Text, Text)
vars_list() -> List<(Text, Text)>

VarError is NotPresent | NotUnicode(List<Byte>).

Standard locations

home_dir() -> Maybe<Text> // HOME or USERPROFILE
user() -> Maybe<Text> // USER or USERNAME
path() -> Maybe<Text> // PATH
shell() -> Maybe<Text> // SHELL or COMSPEC
locale() -> Maybe<Text> // LANG / LC_*
temp_dir() -> Text // TMPDIR/TMP/TEMP or /tmp

Platform info

os_name() -> Text // "macos", "linux", "windows"
arch() -> Text // "aarch64", "x86_64", ...
os_family() -> Text // "unix" or "windows"

Exit

exit(code) -> !
exit_success() -> ! // 0
exit_failure() -> ! // 1

Path utilities

split_paths(path_str) -> List<Text> // splits PATH-style string

Data — dynamic typed value

When you genuinely don't know the schema (e.g., reading arbitrary JSON configuration), Data is the JSON-like dynamic value:

type Data is
| Null
| Bool(Bool)
| Int(Int)
| Float(Float)
| Text(Text)
| Array(List<Data>)
| Object(Map<Text, Data>);

Construction & parsing

Data.null() Data.from_int(42) Data.from_text("hi")
Data.empty_object() Data.empty_array()
parse_json(input) -> Result<Data, DataError>

Type predicates and accessors

d.is_null() d.is_bool() d.is_int() d.is_float() d.is_text()
d.is_array() d.is_object() d.is_number()
d.as_bool() d.as_int() d.as_float() d.as_text()
d.as_array() d.as_object()
d.as_array_mut() d.as_object_mut()
d.type_name() -> Text

Object / array operations

d.get(key) d.get_mut(key) d.contains_key(key)
d.set(key, value) -> Result<(), DataError>
d.remove(key) -> Maybe<Data>
d.at(index) d.at_mut(index)
d.push(value) -> Result<(), DataError>
d.pop() -> Maybe<Data>
d.len() d.is_empty()
d.keys() d.values()

Path access, merging, output

d.path("user.address.city") -> Maybe<&Data>
d.merge(&other) d.deep_merge(&other)
d.to_json() d.to_json_pretty()
d.to_string() d.to_number()

DataError

type DataError is
| TypeMismatch
| KeyNotFound(Text)
| IndexOutOfBounds(Int)
| ParseError(Text)
| InvalidCast;

For typed schemas, prefer dedicated record types with @derive(Serialize, Deserialize) — see serde.vr below.


Serialisation — Serialize / Deserialize

type Serialize is protocol {
fn serialize<S: Serializer>(&self, s: &mut S) -> Result<S.Ok, S.Error>;
}
type Deserialize is protocol {
fn deserialize<D: Deserializer>(d: &mut D) -> Result<Self, D.Error>;
}

The format is supplied by an implementation of the dual Serializer / Deserializer protocols (one per format: JSON, TOML, YAML, …). Most user types just @derive(Serialize, Deserialize) and let an external cog (e.g. toml, serde_json-equivalent) drive the format.

Helper builders:

ListSerializer::serialize_element(&value)
MapSerializer::serialize_key(&k); ::serialize_value(&v)
RecordSerializer::serialize_field(name, &value)

SerdeError is the common error: constructors include unexpected_type(expected, found), missing_field(name), unknown_field(name).


error — backtraces and chains

type StackFrame is { function: Text, file: Text, line: Int, column: Int };
type Backtrace is { frames: List<StackFrame> };

Backtrace::capture() -> Backtrace // current stack (best-effort)
Backtrace::from_frames(frames) -> Backtrace
bt.frames() / bt.is_empty() / bt.len()

ErrorProtocol

type ErrorProtocol is protocol extends ErrorSource {
fn message(&self) -> Text;
fn backtrace(&self) -> Maybe<&Backtrace>;
}

Chain rendering

format_error_chain(&error) -> Text // walks .source() and prints all
match result {
Result.Err(e) => eprint(format_error_chain(&e)),
Result.Ok(_) => (),
}

log — structured logging protocol

type LogLevel is Trace | Debug | Info | Warn | Error;

type Logger is protocol {
fn log(&self, record: &LogRecord);
fn is_enabled(&self, level: LogLevel) -> Bool;
}

type LogRecord is {
level: LogLevel,
message: Text,
module_path: Maybe<Text>,
file: Maybe<Text>,
line: Maybe<Int>,
};

Convenience functions (require Logger in context)

fn handle(req: Request) using [Logger] {
info(&"received request");
debug(&f"path = {req.path}");
if !req.is_authenticated() {
warn(&f"unauthorised access from {req.remote_addr}");
}
error(&f"unexpected: {err}");
}

Backends

NullLogger (no-op, useful in tests). Real backends are in user code or third-party cogs (file logger, journald, syslog, …).


coinductive — productivity & bisimulation analysis

For corecursive function bodies. Most users will not import this directly; it backs the cofix modifier's productivity check.

type CorecursiveCall is { callee: Text, guard_depth: Int };
type ProductivityResult is Productive | NonProductive { unguarded: List<Text> };

corec_call(callee, depth) check_productivity(calls)
is_guarded(call)
observation(label, payload) trace(steps)
trace_prefix(t, n)
observations_equal(a, b)
bisimilar_up_to(left, right, depth) // BisimulationResult

Primitive methods (primitives.vr)

Inherent methods on the built-in numeric / character types. Selected highlights — see source for full list.

Int (64-bit signed)

constants: Int.MIN Int.MAX Int.BITS
predicates: is_positive, is_negative, is_zero, is_power_of_two
arithmetic: abs, signum, pow(n), min, max, clamp
checked: checked_add, checked_sub, checked_mul, checked_div, ...
wrapping: wrapping_add, wrapping_sub, wrapping_mul, ...
saturating: saturating_add, saturating_sub, saturating_mul
overflowing: overflowing_add (-> (T, Bool)), ...
bits: leading_zeros, trailing_zeros, count_ones, count_zeros,
swap_bytes, reverse_bits, rotate_left, rotate_right
bytes: to_le_bytes, to_be_bytes, from_le_bytes, from_be_bytes
conversion: to_float, to_binary, to_hex, to_octal, to_text, parse_int
euclidean: div_euclid, rem_euclid
range: in_range, ilog2, ilog10, abs_diff

Float (64-bit)

constants: Float.MIN Float.MAX Float.MIN_POSITIVE Float.NAN
Float.INFINITY Float.NEG_INFINITY
classify: is_nan, is_infinite, is_finite, is_normal,
is_sign_positive, is_sign_negative
arithmetic: abs, signum, trunc, fract, round, ceil, floor,
sqrt, cbrt, pow(n), exp, log, log10, log2
trig: sin, cos, tan, asin, acos, atan, atan2
hyper: sinh, cosh, tanh, asinh, acosh, atanh
ops: min, max, clamp, copysign, fma, hypot
conversion: to_int, to_bits, from_bits, to_string, parse_float

Bool

.count() // count of `true` in a slice (extension idiom)
.to_int() // 0 or 1
.to_text() // "true" / "false"
parse_bool(text)

Char

classify: is_alphabetic, is_numeric, is_whitespace, is_control,
is_uppercase, is_lowercase
case: to_uppercase, to_lowercase
encoding: encode_utf8, escape_debug
constants:Char.MIN Char.MAX Char.UNICODE_LIMIT

Byte

is_ascii, is_ascii_digit, is_ascii_alphabetic, is_ascii_whitespace
to_int, to_char, to_text
Byte::from_int(n)

See also

  • collectionsList, Map, Set, Deque, BinaryHeap, BTreeMap, BTreeSet.
  • textText (UTF-8 string), Char, formatter, regex, tagged literals.
  • mem — CBGR allocator and the implementation under Heap / Shared.
  • sync — thread-safe equivalents of Cell, atomics, Mutex, RwLock.
  • Language → patterns — pattern syntax used with Maybe / Result.
  • Language → error handlingResult/Maybe/?/throws/try/recover.