Parallel work is explicit through concurrent; the language fixes result shape, timeout fallback, fault propagation, and type compatibility without inventing an implicit async model.
Policy
concurrent { named: expression } is a plain join. The public-docs default is concurrent(timeout: 3s) { ... } else { fallback }. Named arms evaluate concurrently and successful completion returns a record with one field per arm. The timeout fallback runs only when the deadline wins and must be type-compatible with that record; no partial record is exposed.
Specified behavior
A fault in an arm before timeout faults the whole expression and does not select else. An Err is an ordinary arm value. Abandoned work after timeout and its cancellation are runtime policy; later faults from that work are not observed by the expression. Duration literals are adjacent integer plus ms, s, or m, only in the timeout clause. Arm names are unique and become result field names.
Constraints and loud decline
A join cannot have else, and a timeout form cannot omit else. 3 s, property durations such as .seconds, duplicate arm names, an incompatible fallback, partial-result access, and claims that else handles failure are rejected. The language specifies no arm execution or completion order beyond named result association and no deterministic interleaving guarantee.
Deferred boundary
async, await, automatic async I/O, futures, user task handles, cancellation semantics, general duration arithmetic, scheduling fairness, deterministic interleaving, and portable abandoned-task cleanup are outside the language. Toolchain pages may describe measured implementation behavior without promoting it to semantics.
Worked example
function loadUser(id: int) -> Option<string> { Some("Ada") }
function loadPosts(id: int) -> Array<string> { ["first", "second"] }
let dashboard = concurrent(timeout: 3s) {
user: loadUser(7)
posts: loadPosts(7)
} else {
{ user: None, posts: [] }
}