/*:#localized(key: "SendableClosuresIntro")
 # `@Sendable` closures: what a detached task demands of you

 Those errors are really about one thing: a closure that runs in a *different*
 isolation domain from where you wrote it must be **`@Sendable`**: safe to hand
 off and run concurrently. That's the closure you pass to `Task.detached { }`
 (and to a `TaskGroup`). To keep it safe, a `@Sendable` closure is restricted in
 what it may capture:

 * It may capture **Sendable** values freely (they're safe to carry across).
 * It **may not** capture a non-Sendable type like a mutable class (that's the
 `OrderCount` error).
 * It **may not** capture a local `var` and mutate it, because that `var` lives
 in the outer domain and the closure runs in another: a race by construction.

 That last one bites people, so see it directly:

 ```swift
 var runningTotal = 0

 Task.detached {
     runningTotal += 1   // will not compile: mutated from another domain
     print(runningTotal)
 }
 ```

 The compiler rejects the mutation: *"main actor-isolated var 'runningTotal' can
 not be mutated from a nonisolated context."* The fix is the same family of
 answers: don't share mutable state across the boundary. Compute a value and let
 the task *return* it, or route the mutation through an actor:
 */
//#-editable-code
import PlaygroundSupport

PlaygroundPage.current.needsIndefiniteExecution = true

actor OrderCount {
    private(set) var total = 0

    func increment() {
        total += 1
    }
}

let counter = OrderCount()   // the actor from before

Task.detached {
    await counter.increment()
    print("Counted: \(await counter.total)")
    PlaygroundPage.current.finishExecution()
}
//#-end-editable-code
/*:#localized(key: "SendableClosuresWrap")
 Once you internalize "a `Task` closure can only carry Sendable things," most of
 these errors read as helpful reminders rather than obstacles.

 [Previous](@previous)  |  page 9 of 11  |  [Next: Swift 6: Compile-Time Safety](@next)
 */
