Async & Concurrency
Maxon supports concurrency via async and await with green threads scheduled across multiple OS worker threads. Each async call spawns a lightweight green thread with a growable stack (starting at 4KB). The runtime uses a GMP (Goroutine-Machine-Processor) scheduler with per-worker local queues, work stealing, and IOCP-based overlapped I/O.
Spawning Green Threads
Use async before a function call to spawn a green thread:
var promise = async someFunction(arg1, arg2)The async expression returns a promise value that can be awaited later.
Awaiting Results
Use await to wait for a green thread to complete and retrieve its result:
var result = await promiseIf the green thread has already completed, await returns immediately. Otherwise, the current thread yields until the result is ready.
Parallel Execution
Multiple green threads can run concurrently:
var p1 = async taskA()var p2 = async taskB()var r1 = await p1var r2 = await p2Void Functions
Functions that return no value can also be spawned as green threads:
var p = async doWork()await pThrowing Async Functions
Async functions that throw require try await instead of plain await:
var p = async mayFail(true)var result = try await p otherwise 0The try await syntax supports the same otherwise clauses as try on synchronous calls:
try await p otherwise <default>— use a default value on errortry await p otherwise panic("msg")— panic on errortry await p otherwise ignore— for void throwing functionstry await p otherwise return -1(orbreak/continue/throw ...) — run a single statement on errortry await p— propagate the error (inside a throwing function)
Cancellation
A promise can be cancelled via the .cancel() method:
var p = async longRunning()p.cancel()Cancelling a green thread stops it at its next yield point. The green thread’s stack is freed.
Typed promises in collections
Promises can be stored in collections and struct fields by declaring an explicit Promise with T type. The compiler boxes the green-thread handle into a Promise<T> struct at the storage site and unboxes it at the matching await. This pattern lets you fan out N tasks and join them in a second loop:
typealias IntPromise = Promise with Integertypealias IntPromiseArray = Array with IntPromise
var arr = IntPromiseArray.create()for i in 0 upto n 'spawn' arr.push(async compute(i))end 'spawn'var total = 0for p in arr 'join' total = total + await pend 'join'Restrictions
asynccan only be used on direct function calls (not closures or indirect calls)asynccan only target functions that yield (contain I/O operations orawaitpoints)
Key Properties
- Multi-threaded — green threads are distributed across OS worker threads (one per CPU core)
- Work stealing — idle workers steal from busy workers’ local queues for load balancing
- Cooperative scheduling — context switches at
awaitpoints and I/O operations - Growable stacks — 4KB initial, doubles when needed
- Thread-safe memory — atomic reference counting and lock-protected shared state
- Fire-and-forget safe — unawaited green threads are drained at program exit