Skip to main content
v0.13.0

Runtime

Panics

A panic is a hard, unrecoverable runtime errorD1. It prints a message and exits the process with a non-zero status. Panics cannot be caught.

Panics are triggered by:

  • .yolo() on None or an Err
  • Out-of-bounds array access
  • Integer division by zero
  • assert(false) or assert(false, msg)
  • panic(msg), called directly
Formal rules
Dynamic Semantics №1

A panic prints its message, terminates the process with a non-zero status, and cannot be caught. Calling panic, a failing assert, .yolo() on an absent or error variant, out-of-bounds array access, and integer division by zero trigger a panic.

Built-in Functions

These are available in every module without any import declaration (provided by std::core auto-import):

NameSignatureDescription
print<T>(x: T)Print to stdout, no newline
println<T>(x: T)Print to stdout with newline
clock() -> i64Unix timestamp in milliseconds
assert(cond: boolean)Panic with "assertion failed" if cond is false
assert(cond: boolean, msg: String)Overload: panic with msg if cond is false
dbg<T>(x: T) -> TPrint [dbg] <value> to stderr and return the value unchanged
panic(msg: String) -> !Panic unconditionally with msg (RFC-0078)

assert is overloaded — the two-argument form carries the panic messageD2.

panic's return type ! coerces to whatever type its calling context expectsNever type L2 — see §Never type.

print and println require their argument to implement DisplayL1 (print<T: Display>): passing a struct or enum with no Display implementation is a compile-time error. A value whose type implements Display is printed through that implementation's to_stringD1 — user structs and enums, not only the built-in primitives.

String length is a method, not a free function: "hello".len() returns the number of characters (Unicode scalar values). Strings are concatenated with the + operator.

Formal rules
Legality Rule №1

print and println accept only values whose type implements Display.

Dynamic Semantics №1

print writes a Display value's to_string result to stdout without a newline; println writes the same result followed by a newline.

Dynamic Semantics №2

assert(false) panics with "assertion failed"; assert(false, msg) panics with msg.

Dynamic Semantics №3

dbg(v) writes its debug rendering to stderr and evaluates to v unchanged.

Dynamic Semantics №4

clock() returns the current Unix timestamp in milliseconds.

Built-in Aspects

The following aspects are pre-implemented for built-in types:

Display

aspect Display {
fun to_string(&self) -> String;
}

i64, f64, boolean, String, and Char implement DisplayL1. .to_string() returns the canonical string representation. print and println accept any Display type.

Formal rules
Legality Rule №1

i64, f64, boolean, String, and Char have built-in Display implementations whose to_string methods return their canonical string representations.

Tested by (2)

Iterable<T>

aspect Iterable<T> {
fun next(&var self) -> Perhaps<T>;
}

T[] (array) and Range (from .. / ..=) implement Iterable<T>L1. User-defined types may implement it to be usable in for-in.

Formal rules
Legality Rule №1

Arrays and ranges implement Iterable<T>; a user-defined type is usable in for-in only when it implements that aspect.

From<S>

aspect From<S> {
fun from(value: S) -> Self;
}

i64 implements From<f64> (truncating cast) and f64 implements From<i64>L1. The as operator desugars to T::from(value)Type casting D1. User-defined types may implement From<S> to enable as casts and ? error coercion.

Formal rules
Legality Rule №1

i64 implements From<f64> and f64 implements From<i64>; user-defined From<S> implementations make their target type available for as casts and ? error coercion.

Tested by (2)

String Methods

Utilities since v0.9.0. All index-based operations count Unicode scalar values (matching .len()), and are total — out-of-range indices clamp or return None rather than panicking.

MethodSignatureDescription
.len()() -> i64Number of characters (Unicode scalars)
.is_empty()() -> booleanWhether the string has no characters
.to_string()() -> StringReturns the string itself
.to_upper()() -> StringUppercased copy
.to_lower()() -> StringLowercased copy
.trim()() -> StringWhitespace removed from both ends
.trim_start()() -> StringLeading whitespace removed
.trim_end()() -> StringTrailing whitespace removed
.contains(needle)(String) -> booleanWhether needle occurs in the string
.starts_with(prefix)(String) -> booleanWhether the string begins with prefix
.ends_with(suffix)(String) -> booleanWhether the string ends with suffix
.index_of(needle)(String) -> Perhaps<i64>Scalar index of the first occurrence, or None
.split(sep)(String) -> String[]Split on each sep (empty sep ⇒ whole string)
.replace(from, to)(String, String) -> StringReplace every from with to
.repeat(n)(i64) -> StringThe string repeated n times (n <= 0"")
.chars()() -> Char[]The characters as an array
.char_at(i)(i64) -> Perhaps<Char>Character at scalar index i, or None
.substring(start, end)(i64, i64) -> StringScalar range [start, end), indices clamped
Associated functionSignatureDescription
String::join(parts, sep)(String[], String) -> StringConcatenate parts with sep between each

Strings are concatenated with the + operator.

Formal rules
Dynamic Semantics №1

String utility methods operate on Unicode scalar values; index-based operations are total, clamping a slice boundary and returning None for an absent character or search result rather than panicking.

Referenced by: rfc-0057

Array Methods

T[] and [T; N] both expose:

MethodSignatureDescription
.len()() -> i64Number of elements
Formal rules
Dynamic Semantics №1

Calling .len() on either T[] or [T; N] returns its number of elements.

Char Methods

Sincev0.8.0
Method / FunctionSignatureDescription
u32::from(c)D1(Char) -> u32Unicode scalar value as a u32
Char::from(n)D1(u32) -> CharConstruct from a code point; runtime error if not a valid scalar value
.to_string()() -> StringSingle-character string
Formal rules
Dynamic Semantics №1

u32::from(c) returns c's Unicode scalar value, and Char::from(n) returns the matching character or raises a runtime error when n is not a valid Unicode scalar value. A character's to_string() result is its one-character string.

Core Sum Types

SinceCore methodsv0.9.0.yolo(), .ok_or(), .map_err(), and .ok()v0.10.0

Perhaps<T> and Result<T, E> are the core optional/fallible types, both in std::core and available unqualified. Their combinator methods let them be used in pipelines without explicit match:

Perhaps<T>Some { value: T } or None:

MethodSignatureDescription
.is_some()() -> booleanWhether this is Some
.is_none()() -> booleanWhether this is None
.map(f)<U>((T) -> U) -> Perhaps<U>Transform the value, passing None through
.and_then(f)<U>((T) -> Perhaps<U>) -> Perhaps<U>Chain a Perhaps-returning function
.unwrap_or(d)(T) -> TThe value, or d when None
.unwrap_or_else(f)(() -> T) -> TThe value, or f() when None
.yolo()() -> TThe value, or panics (R0013) when None
.ok_or(error)<E>(E) -> Result<T, E>Some becomes Ok; None becomes Err(error)

Result<T, E>Ok { value: T } or Err { error: E }:

MethodSignatureDescription
.is_ok()() -> booleanWhether this is Ok
.is_err()() -> booleanWhether this is Err
.map(f)<U>((T) -> U) -> Result<U, E>Transform the success value, passing Err through
.and_then(f)<U>((T) -> Result<U, E>) -> Result<U, E>Chain a Result-returning function
.unwrap_or(d)(T) -> TThe success value, or d when Err
.unwrap_or_else(f)(() -> T) -> TThe success value, or f() when Err
.yolo()() -> TThe success value, or panics (R0013) when Err, including the error's debug representation
.map_err(f)<F>((E) -> F) -> Result<T, F>Transform the error value, passing Ok through
.ok()() -> Perhaps<T>Ok becomes Some; Err becomes None, discarding the error
Formal rules
Dynamic Semantics №1

The listed Perhaps<T> and Result<T, E> combinators operate on their corresponding sum variants: transforms preserve the non-selected variant, and predicates report which variant is present.

Referenced by: rfc-0057

List<T>

Sincev0.9.0

List<T> is the growable collection type in std::core, available unqualified.

Sincev0.12.0List<T>.set(i, value) overwrites an element in place

.set(i, value) was added alongside RFC-0126 because index assignment through an immutable T[] no longer works. It gives in-place algorithms, such as bubble sort, an operation for replacing an element in a List<T>.

Method / functionSignatureDescription
List::new()() -> List<T>A new empty list
List::from(arr)(T[]) -> List<T>A list with a copy of the array's elements
.push(x)(&var self, T)Append an element
.pop()(&var self) -> Perhaps<T>Remove and return the last element
.len()() -> i64Number of elements
.get(i)(i64) -> Perhaps<T>Element at index i, or None
.set(i, value)(&var self, i64, T) -> Perhaps<T>Overwrite the element at i; returns the replaced value, or None if i is out of bounds
.as_slice()() -> T[]The backing array
.map(f)<U>((T) -> U) -> List<U>A new list of f applied to each element
.filter(pred)((T) -> boolean) -> List<T>The elements satisfying pred
.fold(init, f)<A>(A, (A, T) -> A) -> AReduce to a single value, left to right
.find(pred)((T) -> boolean) -> Perhaps<T>The first element satisfying pred
.concat(other)(&List) -> List<T>This list's elements followed by other's
Formal rules
Dynamic Semantics №2

List<T> collection and iteration methods are methods of List<T> in std::core, not free functions in separate collection or iteration modules.

Referenced by: rfc-0057

Dynamic Semantics №1

List::from(source) copies the elements of source, so mutating the resulting list does not mutate that source.

Referenced by: rfc-0054

OsError

Sincev0.9.0

OsError is the error type returned by the host-backed standard-library modules (std::fs, std::process). It is in std::core (available unqualified) and implements Display.

MethodSignatureDescription
.message()() -> StringThe human-readable error description
Formal rules
Legality Rule №1

Host-backed fallible APIs use OsError, rather than String, as their error type; OsError is available from std::core and implements Display.

Referenced by: rfc-0057

Standard Library Modules

These modules are not auto-imported — a program must import them explicitly (e.g. import std::fs::{read_to_string, write_string};). Their operations are host-backed.

std::env

Read-only process environment inspection.

FunctionSignatureDescription
get(name)(String) -> Perhaps<String>The value of an environment variable, or None
vars()() -> EnvVar[]All environment variables (EnvVar { name, value })
Formal rules
Dynamic Semantics №1

std::env exposes read-only process-environment inspection through get and vars; it is an explicitly imported host-backed module, not part of the automatic prelude.

Referenced by: rfc-0057

std::fs

Text-oriented file operations. Fallible operations return Result<_, OsError>.

FunctionSignatureDescription
read_to_string(path)(String) -> Result<String, OsError>Read an entire file into a string
write_string(path, s)(String, String) -> Result<(), OsError>Write s, replacing any existing file
append_string(path, s)(String, String) -> Result<(), OsError>Append s, creating the file if absent
exists(path)(String) -> booleanWhether a file or directory exists
read_dir(path)(String) -> Result<String[], OsError>The entry names within a directory
create_dir(path)(String) -> Result<(), OsError>Create a single directory
create_dir_all(path)(String) -> Result<(), OsError>Create a directory and all parents
remove_file(path)(String) -> Result<(), OsError>Remove a file
remove_dir(path)(String) -> Result<(), OsError>Remove an empty directory
remove_dir_all(path)(String) -> Result<(), OsError>Remove a directory and its contents
Formal rules
Dynamic Semantics №1

std::fs is an explicitly imported host-backed module whose text-oriented file operations have the signatures listed above and report fallible outcomes as Result<_, OsError>.

Referenced by: rfc-0057

std::process

Command-line arguments and shell-free synchronous subprocess execution.

FunctionSignatureDescription
args()() -> String[]The process command-line arguments
run(command, args)(String, String[]) -> Result<ProcessOutput, OsError>Run command with args, capturing output

run executes the command directly — there is no shell, so quoting and shell expansion never apply. A non-zero exit status is a successful Ok result, not an error; only a failure to launch the command is an Err. The result type is ProcessOutput { status: i64, stdout: String, stderr: String }.

Formal rules
Dynamic Semantics №1

std::process::run launches command directly with args, without shell parsing. A launched program returns Ok(ProcessOutput) even for a non-zero exit status; only failure to launch returns Err(OsError).