Swift Concurrency Proposal Index

This thread has been locked by a moderator; it no longer accepts new replies.

Swift concurrency is an important part of my day-to-day job. I created the following document for an internal presentation, and I figured that it might be helpful for others.

If you have questions or comments, put them in a new thread here on DevForums. Use the App & System Services > Processes & Concurrency topic area and tag it with both Swift and Concurrency.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"


Swift Concurrency Proposal Index

This post summarises the Swift Evolution proposals that went into the Swift concurrency design. It covers the proposal that are implemented in Swift 6.0, plus a few additional ones that aren’t currently available.

The focus is here is the Swift Evolution proposals. For general information about Swift concurrency, see the documentation referenced by Concurrency Resources.

Swift 6.0

The following Swift Evolution proposals form the basis of the Swift 6.0 concurrency design.

SE-0176 Enforce Exclusive Access to Memory

link: SE-0176

notes: This defines the “Law of Exclusivity”, a critical foundation for both serial and concurrent code.

SE-0282 Clarify the Swift memory consistency model ⚛︎

link: SE-0282

notes: This defines Swift’s memory model, that is, the rules about what is and isn’t allowed when it comes to concurrent memory access.

SE-0296 Async/await

link: SE-0296

introduces: async functions, async, await

SE-0297 Concurrency Interoperability with Objective-C

link: SE-0297

notes: Specifies how Swift imports an Objective-C method with a completion handler as an async method. Explicitly allows @objc actors.

SE-0298 Async/Await: Sequences

link: SE-0298

introduces: AsyncSequence, for await syntax

notes: This just defines the AsyncSequence protocol. For one concrete implementation of that protocol, see SE-0314.

SE-0300 Continuations for interfacing async tasks with synchronous code

link: SE-0300

introduces: CheckedContinuation, UnsafeContinuation

notes: Use these to create an async function that wraps a legacy request-reply concurrency construct.

SE-0302 Sendable and @Sendable closures

link: SE-0302

introduces: Sendable, @Sendable closures, marker protocols

SE-0304 Structured concurrency

link: SE-0304

introduces: unstructured and structured concurrency, Task, cancellation, CancellationError, withTaskCancellationHandler(…), sleep(…), withTaskGroup(…), withThrowingTaskGroup(…)

notes: For the async let syntax, see SE-0317. For more ways to sleep, see SE-0329 and SE-0374. For discarding task groups, see SE-0381.

SE-0306 Actors

link: SE-0306

introduces: actor syntax

notes: For actor-isolated parameters and the nonisolated keyword, see SE-0313. For global actors, see SE-0316. For custom executors and the Actor protocol, see SE-0392.

SE-0311 Task Local Values

link: SE-0311

introduces: TaskLocal

SE-0313 Improved control over actor isolation

link: SE-0313

introduces: isolated parameters, nonisolated

SE-0314 AsyncStream and AsyncThrowingStream

link: SE-0314

introduces: AsyncStream, AsyncThrowingStream, onTermination

notes: These are super helpful when you need to publish a legacy notification construct as an async stream. For a simpler API to create a stream, see SE-0388.

SE-0316 Global actors

link: SE-0316

introduces: GlobalActor, MainActor

notes: This includes the @MainActor syntax for closures.

SE-0317 async let bindings

link: SE-0317

introduces: async let syntax

SE-0323 Asynchronous Main Semantics

link: SE-0323

SE-0327 On Actors and Initialization

link: SE-0327

notes: For a proposal to allow access to non-sendable isolated state in a deinitialiser, see SE-0371.

SE-0329 Clock, Instant, and Duration

link: SE-0329

introduces: Clock, InstantProtocol, DurationProtocol, Duration, ContinuousClock, SuspendingClock

notes: For another way to sleep, see SE-0374.

SE-0331 Remove Sendable conformance from unsafe pointer types

link: SE-0331

SE-0337 Incremental migration to concurrency checking

link: SE-0337

introduces: @preconcurrency, explicit unavailability of Sendable

notes: This introduces @preconcurrency on declarations, on imports, and on Sendable protocols. For @preconcurrency conformances, see SE-0423.

SE-0338 Clarify the Execution of Non-Actor-Isolated Async Functions

link: SE-0338

note: This change has caught a bunch of folks by surprise and there’s a discussion underway as to whether to adjust it.

SE-0340 Unavailable From Async Attribute

link: SE-0340

introduces: noasync availability kind

SE-0343 Concurrency in Top-level Code

link: SE-0343

notes: For how strict concurrency applies to global variables, see SE-0412.

SE-0374 Add sleep(for:) to Clock

link: SE-0374

notes: This builds on SE-0329.

SE-0381 DiscardingTaskGroups

link: SE-0381

introduces: DiscardingTaskGroup, ThrowingDiscardingTaskGroup

notes: Use this for task groups that can run indefinitely, for example, a network server.

SE-0388 Convenience Async[Throwing]Stream.makeStream methods

link: SE-0388

notes: This builds on SE-0314.

SE-0392 Custom Actor Executors

link: SE-0392

introduces: Actor protocol, Executor, SerialExecutor, ExecutorJob, assumeIsolated(…)

Notes: For task executors, a closely related concept, see SE-0417. For custom isolation checking, see SE-0424.

SE-0395 Observation

link: SE-0395

introduces: Observation module, Observable

notes: While this isn’t directly related to concurrency, it’s relationship to Combine, which is an important exising concurrency construct, means I’ve included it in this list.

SE-0401 Remove Actor Isolation Inference caused by Property Wrappers

link: SE-0401, commentary

SE-0410 Low-Level Atomic Operations ⚛︎

link: SE-0410

introduces: Synchronization module, Atomic, AtomicLazyReference, WordPair

SE-0411 Isolated default value expressions

link: SE-0411, commentary

SE-0412 Strict concurrency for global variables

link: SE-0412

introduces: nonisolated(unsafe)

notes: While this is a proposal about globals, the introduction of nonisolated(unsafe) applies to “any form of storage”.

SE-0414 Region based Isolation

link: SE-0414, commentary

notes: To send parameters and results across isolation regions, see SE-0430.

SE-0417 Task Executor Preference

link: SE-0417, commentary

introduces: withTaskExecutorPreference(…), TaskExecutor, globalConcurrentExecutor

notes: This is closely related to the custom actor executors defined in SE-0392.

SE-0418 Inferring Sendable for methods and key path literals

link: SE-0418, commentary

notes: The methods part of this is for “partial and unapplied methods”.

SE-0420 Inheritance of actor isolation

link: SE-0420, commentary

introduces: #isolation, optional isolated parameters

notes: This is what makes it possible to iterate over an async stream in an isolated async function.

SE-0421 Generalize effect polymorphism for AsyncSequence and AsyncIteratorProtocol

link: SE-0421, commentary

notes: Previously AsyncSequence used an experimental mechanism to support throwing and non-throwing sequences. This moves it off that. Instead, it uses an extra Failure generic parameter and typed throws to achieve the same result. This allows it to finally support a primary associated type. Yay!

SE-0423 Dynamic actor isolation enforcement from non-strict-concurrency contexts

link: SE-0423, commentary

introduces: @preconcurrency conformance

notes: This adds a number of dynamic actor isolation checks (think assumeIsolated(…)) to close strict concurrency holes that arise when you interact with legacy code.

SE-0424 Custom isolation checking for SerialExecutor

link: SE-0424, commentary

introduces: checkIsolation()

notes: This extends the custom actor executors introduced in SE-0392 to support isolation checking.

SE-0430 sending parameter and result values

link: SE-0430, commentary

introduces: sending

notes: Adds the ability to send parameters and results between the isolation regions introduced by SE-0414.

SE-0431 @isolated(any) Function Types

link: SE-0431, commentary

introduces: @isolated(any) attribute on function types, isolation property of functions values

notes: This is laying the groundwork for SE-NNNN Closure isolation control. That, in turn, aims to bring the currently experimental @_inheritActorContext attribute into the language officially.

SE-0433 Synchronous Mutual Exclusion Lock 🔒

link: SE-0433

introduces: Mutex

SE-0434 Usability of global-actor-isolated types

link: SE-0434, commentary

notes: This loosen strict concurrency checking in a number of subtle ways.

SE-0442 Allow TaskGroup's ChildTaskResult Type To Be Inferred

link: SE-0442

notes: This represents a small quality of life improvement for withTaskGroup(…) and withThrowingTaskGroup(…).

In Progress

The proposals in this section didn’t make Swift 6.0.

SE-0371 Isolated synchronous deinit

link: SE-0371

availability: Swift 6.1

introduces: isolated deinit

notes: Allows a deinitialiser to access non-sendable isolated state, lifting a restriction imposed by SE-0327.

SE-0406 Backpressure support for AsyncStream

link: SE-0406

availability: returned for revision

notes: Currently AsyncStream has very limited buffering options. This was a proposal to improve that. This feature is still very much needed, but it’s not clear whether it’ll come back in anything resembling this guise.

SE-0449 Allow nonisolated to prevent global actor inference

link: SE-0449

availability: Swift 6.1

SE-NNNN Closure isolation control

link: SE-NNNN

introduces: @inheritsIsolation

availability: not yet approved

notes: This aims to bring the currently experimental @_inheritActorContext attribute into the language officially.

Boost
Swift Concurrency Proposal Index
 
 
Q