Renderingen-US

Experimental through version 1. Version 0 was alpha. This is the first language release: the interface is relatively stable, not frozen. Nothing is promised stable until version 2.

trapped

Translation status: English reader-locale proof. Term names and code fences follow the en pack; supporting prose may still be English.

The result of a capture boundary: trap { ... } reifies the error channel into a value read by match.

Syntax: trapped<R, T>

Category#

errors

Examples#

radix/corpus/trapped/trapped.fab (canonical · type)#

The result of a capture boundary: trap { ... } reifies the error channel into a value read by match.

# =============================================================================
# trapped — the capture boundary's result value
# =============================================================================
#
# What this teaches:
#   • trap { ... } runs its block and reifies the ⇥ error channel into a value
#     instead of propagating it; the block's trailing expression is the success.
#   • Ruled shape (error model 2026-10-13, grammar/EBNF.md): the result is
#     trapped<R, T>, variants returned { value: R } and thrown { error: T },
#     read with an ordinary match; R and T are separate slots.
#   • On the current compiler the boundary's result checks and runs as the
#     union R ∪ E, so this program matches the members (case int / case
#     string); the returned/thrown variant arms land with the trapped
#     re-typing (need f9d8a611 follow-ups).
#   • trap catches only the ⇥ channel — panic stays fatal; the success and
#     error types collapsing to one type is rejected (trap_union_collapsed).
#
# Common mistakes:
#   • Expecting trap to catch panic or assert — it never does.
#   • Success and error of the same type — the value cannot tell them apart.
#   • Confusing trap with catch — catch is the statement-level handler that
#     binds the payload; trap is the expression that yields the value.
#
# See also: match, throw, catch, defectus
# =============================================================================

fn half(int n) → int ⇥ string {
    if n % 2 ≢ 0 {
        throw "odd"
    }
    return n / 2
}

main {
    # trap { ... } turns the failable call's two exits into one value.
    let _ missed ← trap { half(7) }
    match missed {
        case int let value {
            print "returned §"(value)
        }
        case string let err {
            print "thrown §"(err)
        }
    }

    let _ made ← trap { half(8) }
    match made {
        case int let value {
            print "returned §"(value)
        }
        case string let err {
            print "thrown §"(err)
        }
    }
}

Expected output:

thrown odd
returned 4