# Structured concurrency


`concurrency/main.xo`

```xo
fn square(n: Int) -> Int { n * n }

fn main(os: Os) {
  let sum = scope s {
    let a = s.spawn(fn() { square(3) })
    let b = s.spawn(fn() { square(4) })
    a.await + b.await
  }
  os.stdio.println("sum ${sum}")

  let ch = Chan[Int].new(cap: 8)
  let total = scope s {
    s.spawn(fn() {
      for i in 1..=5 { ch.send(i) }
      ch.close()
    })
    var t = 0
    for x in ch { t += x }
    t
  }
  os.stdio.println("total ${total}")
}
```

Output:

```text
sum 25
total 15
```



- `scope s { ... }` is an expression. `s.spawn(f)` starts a task inside it,
  and `t.await` waits for its result.
- No task outlives its scope. When the body finishes, the scope waits for its
  tasks; when it fails or returns early, it cancels them and waits for them
  to unwind. There are no leaked goroutines to find later.
- If a task fails, the scope cancels its siblings and the error propagates
  like `?`.
- Channels work as in Go: `for x in ch` receives until the channel is closed
  and drained, and `select` waits on several at once.
- Deadlines and cancellation flow down the scope tree, so there is no `ctx`
  parameter to thread through every call.
- `xo test` runs tasks on a deterministic scheduler, and
  `xo test --explore=N` searches other interleavings for a failing one.

