Control Flow
Control flow is expression-oriented where useful, but stays bounded by the VM execution budget. Loops, branches, and matches preserve source spans so runtime diagnostics can point at the responsible construct.
If And Blocks
Section titled “If And Blocks”if can be used as a statement or expression. If an expression-valued if has no else, the untaken branch evaluates to (). Empty or statement-only blocks also evaluate to ().
fn label(score: i64) -> String { if score >= 90 { return "high" } else { return "normal" }}Use for value in source when you only need each value. Use
for index, value in source when you also need the zero-based position of each
value.
The source expression is evaluated once at the start of the loop. Arrays,
ranges, strings, maps, sets, iterators, and host-provided iterables can all be
used when they support iteration.
Map loops yield MapEntry { key, value } records. Use map.values() when the
loop only needs values and map.keys() when it only needs keys.
fn sum(values) -> i64 { let total = 0 for index, value in values { total += value + index } return total}break exits the nearest loop and continue advances it. Infinite loops are still subject to execution budgets.
match compares one value against literal, binding, wildcard, path, tuple-variant, or record-variant patterns. Guards can refine an arm with if.
fn describe(result) -> String { match result { Result::Ok(value) if value > 0 => "positive", Result::Ok(_) => "ok", Result::Err(error) => error, }}Async Functions And Await
Section titled “Async Functions And Await”Declare module functions and script methods with async fn. The postfix
.await operator applies to call expressions and is legal only inside an async
function. Known async callees must be awaited; awaited dynamic calls may resolve
to either synchronous or asynchronous targets.
async fn load_profile(repository, player_id) { return repository.load(player_id).await;}Await preserves sequential script semantics. A suspended invocation resumes
when the embedding executor polls it again; it does not expose task handles,
manual resume, yield, script-level threads, or concurrent use of one Runtime.
Host effects remain checked through capabilities, budgets, and HostAccess.