Async & await
Async functions and await expressions — Stable Extended (not on wasm32). Each feature below: name → explanation → example → output. Runnable gallery: methods → async/await · examples/builtins/async/.
For application code, prefer import "stdlib/async/mod.ny". It exposes NyraRuntime_default, NyraRuntime_run_until, sleep_ms_async, and await_i32 over Nyra's in-tree runtime, so basic async code does not depend on a Tokio-like external executor.
Name: async fn + await
Explanation: async fn call returns a handle immediately; body runs on the global task pool (spawn:task). await at the call site blocks until the result is ready. Import stdlib/async_v1.ny for executor helpers.
allow_extended
import "stdlib/async_v1.ny"
async fn compute(){
return 42
}
fn main() {
let h = compute()
print(await h)
}allow_extended
import "stdlib/async_v1.ny"
async fn compute(){
return 42
}
fn main() -> void {
let h = compute()
print(await h)
}Output:
42
Run: nyra run examples/builtins/async/async_spawn.ny · Gallery: #ex-async-fn
Name: multiple await (state machine)
Explanation: Linear and control-flow async fn bodies compile to cooperative poll loops (async_poll + runtime_executor_tick). await inside if, while, range for.
allow_extended
import "stdlib/async_v1.ny"
async fn chain(){
let _ = await Executor_sleep_ms(5)
let _ = await Executor_sleep_ms(5)
return 100
}
fn main() {
print(await chain())
}allow_extended
import "stdlib/async_v1.ny"
async fn chain(){
let _ = await Executor_sleep_ms(5)
let _ = await Executor_sleep_ms(5)
return 100
}
fn main() -> void {
print(await chain())
}Output:
100
Gallery: #ex-await · nyra run examples/builtins/async/async_state_machine.ny
Name: Future<T>
Explanation: Import stdlib/async/future.ny for typed futures (Future_i32, Future_string, …) and Future_select2_*.
allow_extended
import "stdlib/async/future.ny"
async fn greet(){
await Executor_sleep_ms(10)
return "Nyra async v2"
}
fn main() {
print(await greet())
}allow_extended
import "stdlib/async/future.ny"
async fn greet(){
await Executor_sleep_ms(10)
return "Nyra async v2"
}
fn main() -> void {
print(await greet())
}Output:
Nyra async v2
Gallery: #ex-async-future · nyra run examples/builtins/async/async_future_string.ny
Runtime: promises (async_promise_new, async_promise_complete), await (pumps the executor while waiting), and IO (io_register / kqueue/epoll/select).
Executor
Import stdlib/async_v1.ny for production-style event loops:
Executor_tick(ms)/Executor_poll_ms(ms)— one IO + timer tickExecutor_sleep_ms(ms)— sleep promise (complete aftermswhen the executor runs)Executor_run_until(handle, timeout_ms)— run until a promise completes
Example: examples/async_executor.ny. Tests: tests/nyra/async_executor_test.ny.
Async fn desugar
async fn bodies run on the global task pool (spawn:task); the call site returns a promise handle immediately (non-blocking). Gallery: #ex-async-fn · tests: tests/nyra/async_spawn_desugar_test.ny.
Async channels
Import stdlib/sync/async_channel.ny (also via stdlib/sync/mod.ny). channel_recv_async returns a promise handle completed on the matching send; select with AsyncChannel_select2_i32 / Future_select2_i32. Non-blocking poll: channel_try_recv + channel_try_value. Example: examples/async_channel_select.ny.
State-machine desugar
See state machine example above. await inside spawn/unsafe still uses blocking async_await.
Race detection
nyra race (or nyra build --race) links with ThreadSanitizer (-fsanitize=thread). Prefer nyra race --native for the portable lock-set runtime. Compile-time Send/Sync checks remain the default; use these detectors to catch races in unsafe or FFI.
Extended tier — not available on wasm32. Cross-compile to Windows: see Targets.