Functions, generics, and errors
Functions declare named parameters and an optional return type. A generic
parameter can carry trait bounds inline or in a where clause. Callable
values use fn(T) -> U; add suspends inside the brackets when a stored
callable may suspend, for example fn[suspends](T) -> U.
enum LookupError {
Missing;
}
fn identity<T>(value: T) -> T { value }
fn require(value: Option<i64>) -> i64 fails LookupError {
match value {
.Some(number) => number,
.None => return error .Missing,
}
}
fn next(value: Option<i64>) -> i64 fails LookupError {
require(value)? + 1
}
fn main() {
match next(.Some(identity(41))) {
.Ok(value) => println(value),
.Err(_) => println("missing"),
}
}
Ownership parameters and receivers
An ordinary parameter borrows or copies according to its type. Write
consume value: T when a call transfers an owned value. Method receivers
are self, var self when the method mutates a value receiver, or
consume self when the method terminates ownership. These modifiers are
part of the public API contract and appear in the generated reference.
Closures use |value: T| expression or |value: T| { ... }. A stored
closure's callable type can also specify var, once, clone, and
suspends capabilities in brackets. The unqualified form is repeated and
read-only.
Arguments and suspension
Positional arguments come before named arguments; named arguments may then appear in any order. Parameters with a default expression may be omitted. Arguments evaluate left to right as written, followed by omitted defaults in parameter order. Parameter names are therefore part of a public API. Closures and values of function type accept positional arguments only, because their types retain no parameter names or defaults.
Hew has no async fn or for await syntax. Suspension is inferred from a
named function's body, and ordinary calls wait when needed. A stored
callable must state that possibility as fn[suspends](T) -> U; a callable
type without the qualifier promises not to suspend.
Typed failure
fn operation() -> T fails E has a success value T and a typed failure
edge E; calling it produces Result<T, E>. Leave through the failure edge
with return error value or ? on a compatible Result. Handle a result
with match, ?, or handle error { ... }. A dropped Result is a compile
error; write _ = operation(); only when discarding it is deliberate.
Option<T> represents presence or absence. ? on an Option propagates
absence only from a function returning Option; it does not invent an
error value. Use expect(reason) when absence or failure is an invariant
violation that should trap.
Generators
gen fn values() -> T declares T as the yielded item type. Calling it
returns a generator handle; writing Generator<T, R> as the declared
return type would instead mean that each yielded item is itself a generator
handle. A for loop drives a generator to completion. A failing generator
declared with fails E yields Result<T, E> items and stops after its
failure item. Generator parameters and captured owners follow the same
borrow and consume rules as ordinary functions.