
## Contracts

Functions can declare preconditions and postconditions, checked at runtime on every call. A failed contract throws `ContractViolation`.

```vary
def divide(a: Int, b: Int) -> Int {
    in {
        b != 0
    }
    return a // b
}

def abs_val(x: Int) -> Int {
    out (r) {
        r >= 0
    }
    if x < 0 {
        return -x
    }
    return x
}
```

`in {}` checks conditions before the body runs. `out(r) {}` checks the return value. `old(expr)` captures a value at function entry for comparison in postconditions. Classes and data types can declare `invariant {}` blocks. See [Contracts](/docs/contracts/) for the full reference.

## Try / except / finally

```vary
def divide(a: Int, b: Int) -> Int {
    in {
        b != 0
    }
    return a // b
}

try {
    let result = divide(10, 0)
} except ValueError as e {
    print("Bad value")
} except Error as e {
    print("Some other error")
} finally {
    print("Always runs")
}
```

`raise ValueError("msg")` throws an error. `raise "msg"` wraps in `RuntimeError`. Built-in error types: `Error`, `RuntimeError`, `TypeError`, `ValueError`, `IOError`, `KeyError`, `IndexError`, `ContractViolation`.

## Result type

`Result[T, E]` represents success or failure without exceptions:

```vary
def safe_divide(a: Int, b: Int) -> Result[Int, Str] {
    if b == 0 {
        return Err("division by zero")
    }
    return Ok(a // b)
}

let r = safe_divide(10, 3)
match r {
    case Ok(value) {
        print(f"got {value}")
    }
    case Err(msg) {
        print(f"failed: {msg}")
    }
}
```

The `?` postfix operator unwraps `Ok` or returns `Err` early from the enclosing function. Use `?else return` for early return with a default value when unwrapping fails:

```vary-snippet
def get_name(id: Int) -> Str {
    let user = find_user(id) ?else return "unknown"
    return user.name
}
```

See [Error handling](/docs/errors/) for the full reference.

## Defer

`defer` schedules a block to run when the enclosing scope exits, regardless of how it exits (normal return, exception, or early return). Deferred blocks run in reverse order of declaration:

```vary-snippet
def process_file(path: Str) -> None {
    let f = open(path)
    defer { close(f) }
    # work with f... cleanup happens automatically
}
```
