Language features
Everything is an expression
No statements. If/else, match, and blocks all return values. The last expression in a block is its value.
result = if x > 0 {
'positive'
} else {
'non-positive'
}
grade = match score {
90..100 -> 'A',
80..90 -> 'B',
else -> 'C',
}Optional values with ?
Functions that might not return a value use ? in their return type. Use 'or' to provide defaults.
fn find_user(id Int) ?User {
if id == 0 {
none
} else {
User{ id: id, name: 'found' }
}
}
user = find_user(0) or User{ id: 0, name: 'guest' }Error handling with !
Functions that can fail use ! with an error type. Handle errors with 'or', or propagate with !.
fn divide(a Int, b Int) Int!DivisionError {
if b == 0 {
error DivisionError{ message: 'divide by zero' }
} else {
a / b
}
}
safe = divide(10, 0) or 0
safe_with_err = divide(10, 0) or err -> -1
result = divide(10, 2)! // propagate errorPattern matching
Match on values, enums, and even literal payloads. Exhaustive checking ensures you handle all cases.
enum Result {
Ok(String),
Err(String),
}
fn handle(r Result) String {
match r {
Ok('special') -> 'matched literal!',
Ok(value) -> 'got: $value',
Err(e) -> 'error: $e',
}
}Structs and enums
Define data with structs. Model variants with enums that can carry payloads.
struct Person {
name String,
age Int,
}
enum Status {
Active,
Inactive,
Banned(String),
}
person = Person{ name: 'alice', age: 30 }
status = Status.Banned('spam')String interpolation
Embed expressions directly in strings with $ for simple variables or ${} for expressions.
name = 'world'
greeting = 'Hello, $name!'
math = 'Result: 7'First-class functions
Functions are values. Pass them around, store them, return them.
fn apply(x Int, f fn(Int) Int) Int {
f(x)
}
double = fn(n Int) Int { n * 2 }
result = apply(5, double) // 10Assertions
Assert conditions that must be true. If they fail, the function returns an error.
fn process(x Int) Int!Error {
assert x > 0, Error{ message: 'must be positive' }
x * 2
}
a = process(5)! // 10
b = process(-1) or err -> 0 // 0