Atoll has one function kind: fn. There is no async fn/await coloring
split. Calls that may suspend retain ordinary call syntax, while explicit
concurrency uses spawn, Task, race, select, and Stream.
| Construct | Purpose | Result |
|---|---|---|
spawn { ... } |
Start a child task | Task[T] |
task.await() |
Join and consume a task | T |
task.cancel() |
Request cancellation | void |
race { ... } |
First completed arm, with loser cancellation | Arm type |
select { ... } |
Dispatch the first ready source | void |
Stream[T] |
Shared bounded channel | Buffered Option[T] values |
There is no spawn.all, async fn, await keyword, or concurrent
construct in the current language.
Execution model
Concurrency is cooperative. A running task keeps executing until a host call, task join, selection, backpressured send, generated safepoint, or another suspension boundary returns control to the scheduler. This is not a promise of arbitrary instruction-level parallelism or a license for unsynchronized shared mutation.
Tasks form a parent-child tree. A spawned computation remains part of that tree even when its handle is discarded. Completion, cancellation, captures, and resource cleanup are therefore structured around task ownership rather than detached operating-system threads.
Choosing a construct
| Need | Construct |
|---|---|
| Start work now and retrieve it later | spawn plus Task.await() |
| Require every concurrent result | Spawn all tasks, then await each |
| Use the first interchangeable result | race |
| Give ready sources different behaviors | select |
| Communicate a sequence with bounded buffering | Stream[T] |
| Ask an owned child and its descendants to stop | Task.cancel() |
Start all independent tasks before awaiting any of them. Awaiting each call immediately is correct but provides no overlap.
Values and handles
Ordinary values passed into a spawned block follow Atoll ownership and capture
rules. Task[T] is a single-result handle. Stream[T] is a copied shared
handle whose copies refer to the same bounded channel.
Raw pointers and borrowed views have tighter rules across suspension because the referenced storage must remain stable and live. Prefer owned values or a standard-library resource wrapper at task boundaries.
Reading order
Begin with Effects and Suspension, then continue through Tasks, Spawning, and Cancellation. Use Streams for communication, Select for heterogeneous readiness, and Race for interchangeable competitors.
Effects describe which functions may suspend, spawn, or cancel. They do not replace typed errors, value ownership, or application-level timeout and retry policies.