The Swift Concurrency Story
For years, one of the missing pieces of the Swift language was the capability to deal with concurrency natively. It wasn't until 2017 when a Concurrency Manifesto for Swift was written by Chris Lattner. The manifesto got a lot of us excited. Personally I found it very interesting and eye opening that one of the possible directions that the language could go was way more than just to add basic support for concurrency.
We had to wait for 2020 to see serious strikes at this. It was then when we saw official plans in the form of Road to Swift 6. With ABI stability behind, the Core Team could focus on new horizons for Swift. It was time for Concurrency!
Even if the original manifesto was just a suggestion, the path the Core Team took is very close to it. That’s why is very nice to have that historical artefact and read it. When you look at the entire Concurrency work done in Swift one the first things you notice is how big the work is. Swift Concurrency Story is big. It’s full of interconnected features all building on top of each other. It's a beautiful design, but it's also a big overwhelming at first.
You can check this Twitter thread to get a feeling of how big the effort was and how many people were involved in it.
It's also important to note that this is still in flux. WWDC gave us the first beta of Xcode 13 which includes a preliminary version of Swift 5.5, which includes part of the entire story. APIs are still changing, some proposals are not even accepted yet, so don't worry if something is not perfect yet. The goal is to have a fully formed system by Swift 6. But it's already totally functional!
Swift Concurrency Story
As you can see in the diagram, there are a lot of parts that form the concurrency story. But don't feel overwhelmed, let's discuss what for me re the most important parts.
For me the best way of visualise this is to first focus on the 4 pillars that form the Swift Concurrency Story: async/await, Structured Concurrency, Async Sequences and Actors.
We will discuss each pillar in detail but I just want to start by summarizing the overall structure:
The first pillar is probably the most visible one: async/await. Everything else is built on top of this, but is very important to understand that on its own it has very little to do with concurrency. We will see what this means later.
The second in the list, and for me the most important of all, is structured concurrency. This on its own is an invisible feature, but the one that makes everything else work flawlessly, unlocking a huge potential of beautiful APIs. We will learn about the theory behind it and why is so much batter than the alternatives we had until now.
Async functions are ideal to return a single value, but in the same way we need arrays we also need async sequences. They are a very important concept when you need to get more than one value asynchronously over time. It also matters because it is probably the feature that will disrupt most existing solutions. There will be more to say about this!
And finally actors. They are not a new concept in programming but is likely that you have heard very little of them. Usually they are used in distributed computing but Swift's implementation is ideal even for user facing applications. This is another topic where we will need to learn the theory behind it and compare it with how it has turned out in practice for Swift.
There are a lot of other topics to talk about but we will get there on time. First, we need to learn the core of the story before we explore the rest of its ecosystem.
Swift Evolution Proposals
If you want to read the proposals that added the functionality to the language I leave here a list of all of them:
- SE-0296: Async/await
- SE-0297: Concurrency Interoperability with Objective-C
- SE-0298: Async/Await: Sequences
- SE-0300: Continuations for interfacing async tasks with synchronous code
- SE-0302: Sendable and @Sendable closures
- SE-0304: Structured concurrency
- SE-0306: Actors
- SE-0310: Effectful read-only properties
- SE-0311: Task Local Values
- SE-0313: Improved control over actor isolation
- SE-0316: Global actors
- SE-0317: async let
- Custom Executors
If you liked this article please consider supporting me