Skip to content
La3 Docs
Browse docs

Functions and Control Flow

Definitions, closures, if, match, loops, ?, and the reader-facing control style.

Functions

Functions are expression-oriented and use the final expression as the return value.

  • return exists for early exits.
  • Tuple returns are used where multiple results are part of the contract.
  • Generic type parameters are constrained with interface bounds.
fn add(a: i32, b: i32) -> i32 {
    a + b
}

Closures

Closures capture values from the surrounding scope and can opt into ownership with move.

The default capture mode is by reference. move takes ownership of captured non-Copy values so the closure can outlive the current stack frame.

let threshold = 100
let exceeds = |x| x > threshold

let base = compute_base()
let scaled = move |x| x * base

Branching

if, match, while let, and loop all behave like expressions, not just statements.

  • match is exhaustive unless a wildcard intentionally catches the rest.
  • if let handles one variant of a sum type without writing the full match.
  • while let repeats while the pattern continues to match.
  • loop { break value } lets the loop itself produce a result.
let label = if score >= 90 { "A" }
             else if score >= 80 { "B" }
             else { "F" }

Errors

Result<T> handles recoverable failure; try/catch covers external exception-style boundaries.

  • ? propagates Err or None out of the current function.
  • unwrap, unwrap_or, and friends stay available for the simple cases.
  • try/catch is reserved for calls into external systems that throw.