std::builtinsBuilt-in functions available in every Hew program.
These functions are always in scope — no import is needed.
They cover I/O, assertions, math, string operations, and
program control flow.
printlnPrint a value followed by a newline.
Accepts any type that implements Display.
println(42);
println("hello");
println(true);
printPrint a value without a trailing newline.
print("Enter name: ");
assertAssert that a condition is true. Panics if condition is false.
assert(x > 0);
assert_eqAssert that two values are equal. Panics with a diff if they differ.
Both arguments must be the same type.
assert_eq(add(1, 2), 3);
assert_neAssert that two values are not equal. Panics if they are the same.
Both arguments must be the same type.
assert_ne(a, b);
absReturns the absolute value of an integer.
let x = abs(-5); // 5
sqrtReturns the square root of a floating-point number.
let r = sqrt(9.0); // 3.0
minReturns the smaller of two integers.
maxReturns the larger of two integers.
to_floatConvert an integer to a floating-point number.
let f = to_float(42); // 42.0
string_concatConcatenate two strings, returning a new string.
let full = string_concat("hello ", "world");
string_lengthReturns the byte length of a string.
to_stringConvert any value to its string representation.
Accepts any type that implements Display — this includes all numeric
primitives, bool, char, string, and user types with a Display impl.
let s = to_string(42); // "42"
let t = to_string(true); // "true"
let u = to_string('x'); // "x"
string_char_atReturns the character (as a char) at the given byte index.
string_equalsTest whether two strings are equal.
string_from_intConvert an integer to a string.
let s = string_from_int(42); // "42"
string_containsTest whether haystack contains needle.
string_starts_withTest whether a string starts with the given prefix.
substringExtract a substring by byte indices [start, end).
let s = substring("hello", 0, 3); // "hel"
string_trimStrip leading and trailing whitespace.
string_to_intParse a string as an integer. Returns 0 on failure.
string_findFind the first occurrence of needle in haystack.
Returns the byte offset, or -1 if not found.
read_fileRead the entire contents of a file as a string.
write_fileWrite a string to a file, creating or overwriting it.
sleep_msPause execution for the given number of milliseconds.
sleepPause execution for the given number of seconds.
exitTerminate the program with the given exit code.
This function never returns.
panicTerminate the program with an error message.
This function never returns.
panic("something went wrong");
LocalPidA process-local actor pid returned by spawn.
LocalPid<T> is accepted by all built-in actor functions (close, link,
monitor, etc.) and by any function that takes dyn Pid<Msg = M>.
Coercion to a remote pid is explicit:
let remote = pid.to_remote_via(node_handle);
RemotePidAn actor pid on a remote node.
Produced by peer-discovery or explicit construction via RemotePid::from_raw.
Does NOT coerce implicitly to LocalPid<T> — remote actors are a distinct class.
.tell is a fail-closed stub until S4 wires up hew_actor_send_remote.
RemotePid::from_raw is scaffolding for S1 tests. .tell fails closed
with SendError::NodeRoutingNotWired until hew_actor_send_remote lands.
SendErrorError returned when a pid send cannot be completed.
FullThe destination mailbox is full.
ClosedThe destination is closed or no longer alive.
NodeRoutingNotWiredCross-node routing has not been wired for this runtime path yet.
LookupErrorError returned when Node::lookup<T>(name) cannot resolve name.
Returned as Err(LookupError::NotFound) when no actor is registered
under name on the current node (or any peer with a gossiped name).
Future variants (e.g. transport-level failures, schema mismatches) are
deferred to follow-on polish; today the runtime collapses every failure
into NotFound since the underlying registry surface is fail-closed
per set_last_error for the diagnostic detail.
NotFoundNo actor is registered under the requested name.
AskErrorError returned when a remote actor ask cannot complete.
Variant order matches the native runtime ask ABI so codegen can project the runtime error discriminant directly into this public enum.
NoErrorInternal no-error sentinel; should not be returned as Err.
NodeNotRunningThe local node is not running.
RoutingFailedThe destination node or actor could not be routed.
EncodeFailedThe request payload could not be encoded.
SendFailedThe request could not be sent.
TimeoutThe caller-supplied timeout elapsed before a reply arrived.
ConnectionDroppedThe remote connection closed before the reply arrived.
PayloadSizeMismatchThe reply payload did not match the expected reply size.
WorkerAtCapacityThe remote ask worker is at capacity.
ActorStoppedThe destination actor is stopped.
MailboxFullThe destination actor mailbox is full.
OrphanedAskA reply arrived after its waiter was gone.
NoRunnableWorkThe runtime had no runnable work while waiting for the reply.
TimeoutErrorError arm of await rx.recv() | after d and await stream.recv() | after d.
Returned as Err(TimeoutError::Timeout) when the deadline fires before an
item arrives. Distinguishes a timeout from a closed channel (Ok(None)).
match await rx.recv() | after 50ms {
Ok(Some(v)) => v, // item received before deadline
Ok(None) => -1, // channel closed (no deadline race)
Err(_) => -2, // deadline fired
}
TimeoutThe deadline fired before the recv completed.
VecIterCursor iterator over a Vec<T> produced by vec.into_iter().
VecIter<T> is the concrete IntoIterator::IntoIter for Vec<T> — it
pairs the owned vector with the current idx cursor so that
for x in v { ... } (for-loop desugar) and the lazy combinators in
std/iter can drive iteration through the trait surface rather than the
per-type *_int / *_str / *_f64 table.
next takes a mutable receiver: each call reads the current element and
then bumps self.idx in place via a field-store. idx advances once per
call until it reaches the vector's length, after which every subsequent
next returns None. The receiver remains Live after exhaustion and
drops at scope exit — see the Iterator trait doc-comment.
Vec is a refcounted heap handle, so the cursor carries the underlying
vector storage by handle (no per-step copy).
Lives in std/builtins.hew rather than std/vec.hew so it registers
alongside the Vec Index impl through register_builtins_hew_impls (the
per-stdlib-module receiver-impl harness only handles a fixed set of
receivers; auto-registration on builtin nominals belongs in builtins).
InstantMonotonic timestamp captured by the runtime.
ActorMsgMessage contract for actor types used behind LocalPid<A> / RemotePid<A>.
Named actors opt into the erased Pid surface by implementing this trait
and binding Msg to the envelope type accepted by .tell / .ask, plus
Reply to the response type returned by .ask.
PidTrait satisfied by both LocalPid<A> and RemotePid<A>.
Future surface target for accepting either local or remote pids. A640:
generic P: Pid sends are fail-closed unless P::Msg is concretely proven
Serializable; local-only dispatch through LocalPid<T> keeps the value
model below.
fn ping<P: Pid>(p: P, msg: P::Msg) -> Result<(), SendError> {
p.tell(msg)
}
IteratorProduce a sequence of values one item at a time.
User-defined iterators implement this trait directly; for loops accept
values whose type implements IntoIterator and walk the resulting
Iterator to bind each yielded Item.
next takes its receiver mutably (var self): iterator implementations
step their internal state in place (cursor advance, decrement remaining,
flush a buffer) and surface successive items through the
Option<Self::Item> return. Callers must hold the iterator in a var
binding so that the mutated receiver remains observable between calls;
binding the iterator with let is rejected by the checker with a
"receiver requires mutable binding" diagnostic.
Iterator methods with mutable receivers keep the iterator Live past
exhaustion; drop fires at scope exit, not at the None return. This is
a deliberate shift from a hypothetical by-move shape: exhaustion is a
Some → None boundary, not a lifetime boundary. Iterator implementations
that own non-shared resources (heap-owning buffers, channel readers)
inherit the "exhaustion ≠ drop" invariant — see the lifecycle-symmetry
invariant in LESSONS.md.
IntoIteratorConvert a value into an Iterator.
for x in expr { ... } desugars to let mut it = expr.into_iter(); loop { match it.next() { Some(x) => ..., None => break } } — the iterable on the
right of in must implement IntoIterator, and the loop binding is typed
as <Self::IntoIter as Iterator>::Item.
IntoIter carries the Iterator<Item = Self::Item> bound so that callers
projecting <T as IntoIterator>::IntoIter::Item always agree with
<T as IntoIterator>::Item. Concrete IntoIterator impls live next to
each collection (Vec, HashSet, HashMap); this trait declaration
reserves the surface only.
IndexBracket indexing surface for values that define an element lookup.
obj[k] type-checks through this trait for user-defined receivers. Vec
keeps its compiler-backed bounds-check/runtime path, with this impl
providing the same trait surface for bounds and associated-type projection.
DisplayConvert a value of type Self into a human-readable string.
Implementing Display for a type lets it flow through print,
println, assert_eq, assert_ne, to_string, len, and stop.
The trait method must return a string derived from the receiver
without invoking print itself (otherwise the output path becomes
recursive).
Blanket impls below cover the primitive numeric kinds, bool,
char, and string; user types add their own impls per receiver.