Parallelism without data races
Concurrency is allowed only when the compiler can prove compatible effect sets and memory regions.
Independent parallel iterations
1normalize(view<f32> samples):2 parallel for usize i = 0; i < samples.size(); i = i + 1:3 samples[i] = clamp(samples[i], -1.0, 1.0)Mutable sample buffer.
A parallel loop requires an independence proof.
Each iteration touches only one element, so distinct indices can be proven disjoint.
Scoped task borrows
1process(view<u8> left, view<u8> right):2 require disjoint(left, right)3 const task a = spawn filter(left)4 const task b = spawn filter(right)5 await a6 await bThe caller proves the mutable regions do not overlap.
Task a borrows left.
Task b borrows right.
Await returns the permission to the parent scope.
Structured concurrency prevents borrowed memory from being outlived.
Shared state
Ordinary mutable data cannot be shared freely. Use semantic synchronization types such as atomic<T>, mutex<T>, and channel<T>. A mutex lock temporarily grants exclusive mutable permission.
Memory order
Atomics default to sequential semantics. Weaker orders such as relaxed, acquire, release, and acquire_release are explicit; nonsense combinations such as load(release) are compile-time errors.