Alpha. Vary is under active development and not ready for production use. Syntax, APIs, performance, and behaviour may change between releases.
Error handling
Contracts
Functions can declare preconditions and postconditions, checked at runtime on every call. A failed contract throws ContractViolation.
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 for the full reference.
Try / except / finally
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:
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:
def get_name(id: Int) -> Str {
let user = find_user(id) ?else return "unknown"
return user.name
}
See Error handling 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:
def process_file(path: Str) -> None {
let f = open(path)
defer { close(f) }
# work with f... cleanup happens automatically
}