Nyx by Example

Try Operator

The ? operator is syntactic sugar for propagating errors. Appending ? to a Result-returning expression either unwraps the Ok value or immediately returns the Err to the caller — without requiring an explicit match.

Code

// Try operator (?): encadenar operaciones que pueden fallar, short-circuit en Err

enum Result {
    Ok(int),
    Err(String)
}

fn parse_positive(s: String) -> Result {
    let n: int = string_to_int(s)
    if n <= 0 {
        return Result.Err("no es positivo: " + s)
    }
    return Result.Ok(n)
}

fn double_it(n: int) -> Result {
    if n > 1000 {
        return Result.Err("numero demasiado grande")
    }
    return Result.Ok(n * 2)
}

// ? propaga el Err automáticamente sin match explícito
fn pipeline(s: String) -> Result {
    let n: int = parse_positive(s)?
    let d: int = double_it(n)?
    return Result.Ok(d + 1)
}

fn show(r: Result) {
    match r {
        Result.Ok(v)  => print("ok: " + int_to_string(v)),
        Result.Err(e) => print("err: " + e)
    }
}

fn main() -> int {
    show(pipeline("42"))     // ok: 85  (42*2+1)
    show(pipeline("-5"))     // err: no es positivo
    show(pipeline("2000"))   // err: numero demasiado grande

    return 0
}

Output

ok: 85
err: no es positivo: -5
err: numero demasiado grande

Explanation

Without ?, every fallible call would require a match expression to check for errors before proceeding. The ? operator automates this: if the result is Ok(v), it unwraps v and continues; if it is Err(e), it immediately returns Err(e) from the enclosing function. The function signature must also return a Result for this to work.

The pipeline function chains two fallible steps: parsing a positive integer and doubling it within a limit. Both lines use ?, so the first error encountered short-circuits the rest of the function. When "-5" is passed, parse_positive returns Err immediately and double_it is never called.

This pattern keeps the happy-path logic clean and readable — pipeline reads almost like sequential imperative code — while preserving complete, explicit error handling. It is the preferred style for multi-step operations in Nyx over deeply nested match expressions.

← Previous Next →

Source: examples/by-example/26-try-operator.nx