BRAIDGROUP
RESEARCH & DEV
20. Documentation

Async and Await

Async Functions

Braid supports asynchronous programming with async fn declarations. An async function does not execute immediately; instead it returns a future that can be awaited. The function body is executed inside an async context managed by the BraidVM.

async fn fetch_data(url: string) -> string {
    return "data from " + url;
}

async fn compute_async(a: int, b: int) -> int {
    return a + b;
}

The await Expression

Use await to pause execution until an async function completes. Theawait expression yields control back to the scheduler, allowing other tasks to run while waiting.

async fn main() {
    let result = await fetch_data("https://api.example.com");
    print("result: " + result);
}

async fn process() {
    let x = await compute_async(10, 20);
    let y = await compute_async(30, 40);
    print("sum: " + (x + y));
}

Futures

When you call an async function, it returns a future. You can store the future in a variable and await it later. Futures represent a computation that will complete at some point.

async fn long_running_task(id: int) -> int {
    let result = id * id;
    return result;
}

async fn main() {
    let future1 = long_running_task(5);
    let future2 = long_running_task(10);
    // both tasks are now running concurrently
    let r1 = await future1;
    let r2 = await future2;
    print("results: " + r1 + ", " + r2);
}

Concurrent Execution with spawn

Combine spawn with async functions to run multiple tasks concurrently. The spawn block creates a green thread that can itself await async operations.

async fn download_file(url: string) -> string {
    return "downloaded: " + url;
}

fn main() {
    spawn {
        let a = await download_file("https://example.com/a.txt");
        print(a);
    };
    spawn {
        let b = await download_file("https://example.com/b.txt");
        print(b);
    };
    print("main continues while downloads run");
}

Async with Channels

Channels work seamlessly with async functions. Await values from a channel without blocking the entire thread.

async fn worker(id: int, ch: channel) {
    let result = id * 100;
    ch.send(result);
}

async fn main() {
    let ch = channel();
    spawn { await worker(1, ch); };
    spawn { await worker(2, ch); };
    spawn { await worker(3, ch); };

    let sum = 0;
    let i = 0;
    while i < 3 {
        let val = await ch.recv();
        sum = sum + val;
        i = i + 1;
    }
    print("total: " + sum);
}

Async Pipeline Pattern

Chain async operations together for a clean data processing pipeline. Each step awaits the previous.

async fn fetch(url: string) -&gt; string {
    return "raw data";
}

async fn parse(data: string) -> string {
    return "parsed: " + data;
}

async fn save(data: string) {
    print("saved: " + data);
}

async fn main() {
    let raw = await fetch("https://api.example.com/data");
    let parsed = await parse(raw);
    await save(parsed);
    print("pipeline complete");
}

Async Loops

Async functions can contain loops that await inside the loop body, processing items one at a time without blocking.

async fn process_batch(items: int[]) {
    let i = 0;
    while i < items.count {
        let result = await compute_async(items[i], 0);
        print("processed " + i + ": " + result);
        i = i + 1;
    }
}

async fn main() {
    let data = [1, 2, 3, 4, 5];
    await process_batch(data);
    print("batch done");
}

Async Best Practices

  • Use spawn for fire-and-forget tasks that don't need a result in the current scope
  • Store futures in variables and await them later to enable concurrency
  • Use channels to communicate results between async tasks
  • Avoid long synchronous loops inside async functions; yield with awaitperiodically
  • Async functions can call regular functions, but regular functions cannotawait