Browse documentation
Data structures

Result

Typed success or recoverable error outcomes, explicit checked access, native validation results, managed ownership and complexity.

Result<T, E> is an import free typed outcome containing either a successful value of T or an error value of E. It lets a function report an expected recoverable outcome through its explicit return type.

Construction and use

aner
fn divide(numerator: Float64, denominator: Float64) -> Result<Float64, String> {
    if denominator == 0.0 {
        return Result.err<Float64, String>(error: "denominator is zero")
    }
    return Result.ok<Float64, String>(value: numerator / denominator)
}
let outcome = divide(6.0, 2.0)
if outcome.is_ok() {
    print(outcome.unwrap())
} else {
    print(outcome.unwrap_err())
}

Result.ok<T, E>(value: T) creates a success. Result.err<T, E>(error: E) creates an error. Both factories require the two explicit type arguments so the inactive alternative has a known type. Success and error payloads are checked against their stated types without implicit conversion.

This is an explicit data contract. Returning an error Result does not throw a runtime exception, and Result does not automatically intercept native failures. A function must choose which expected conditions it represents as values. Unchecked access to the inactive alternative still produces a runtime error.

Native recoverable conversion

Native Date.try_parse, Time.try_parse, DateTime.try_parse, and Duration.try_parse return a Result with their value type and String errors. Bytes.try_from_hex returns Result<Bytes, String>; bytes.try_decode_utf8() returns Result<String, String>. They apply the same strict validation as their failing conversion counterparts, and represent expected malformed input as the error alternative. Resource failures and unrelated runtime errors retain the ordinary execution contract.

aner
let observed = Date.try_parse("2026-02-30")
if observed.is_err() {
    print(observed.unwrap_err())
}

These factory names do not change the accepted input grammar or silently repair values.

Methods

MethodResultContract
is_ok()BoolWhether the active alternative is success.
is_err()BoolWhether the active alternative is error.
unwrap()TReturn success, or fail when the active alternative is error.
unwrap_err()EReturn error, or fail when the active alternative is success.
unwrap_or(default: T)TReturn success, otherwise the supplied same type default.

These methods retain explicit checked access after a condition. unwrap_or evaluates its default expression under ordinary call rules even when the Result succeeds. This release has no propagation operator, automatic exception conversion, pattern matching, or lazy error callback.

Ownership and identity

The immutable managed wrapper owns one active payload slot and traces reference payloads through the shared execution heap. Copies retain wrapper identity. Class and mutable collection payloads keep their existing reference semantics; Result does not deep copy or freeze them. Nested Result and Optional values are permitted, subject to the ordinary static type and heap limits.

Equality compares wrapper identity rather than recursively comparing the active payload. Distinct factories create distinct wrappers. Compare unwrap() or unwrap_err() explicitly after checking the active alternative when value comparison is intended. Result is not an accepted scalar Dictionary key or Set member.

type(value) reports a concrete specialization such as Result<Float64, String>. Checked casts from Any require the same T and E. dtype is unsupported: an outcome descriptor does not supply a homogeneous storage datatype. There is no implicit success/error to Bool conversion.

Errors and limits

Unchecked access to an inactive alternative or a wrapper operation limit failure produces a located runtime error R3404. Wrong static argument types or arities produce E1002. Generic wrapper nesting is limited to 128 and formatted type names to 16 KiB; exceeding these static bounds produces E1007. Shared managed object and value slot limits also apply. A runtime failure retains the normal program or persistent session error contract.

Time and space complexity

The wrapper uses O(1) active state metadata and one active payload slot, plus a generic type descriptor. Materializing or copying a descriptor of size g adds O(g) time and space at construction or value copy boundaries. Branch tests and identity equality perform O(1) active state work plus O(g) receiver descriptor validation at the heap boundary; checked access adds that validation and returned payload copy costs. Payload evaluation, owned value copying, and formatting add the payload's existing time and space costs. Reference payloads retain shared objects instead of duplicating them. Garbage collection follows the execution heap's normal reachable object and slot costs.

Run the complete Result example, and see Optional for typed absence without an error alternative.

Aner documentation · Reference and guides