Swift Evolution Monthly: February-April 2024

Swift 6 around the corner, Swift Backtrace APIs for improved Debugging, Improving Concurrency, a new Swift Steering Workgroup, and much more. Summarizing the best of Swift Evolution from February to April 2024.

Swift Evolution Monthly: February-April 2024

WWDC24 is just a month away and there are 2 ways I'll be involved: Firstly, I'll be in the area for the whole week and join all community events I can! Paul Hudsons great video about his experience in 2023 convinced me that it's worth it even if you didn't get the golden ticket for Apple Park. Maybe we'll meet there? 😊

Secondly, I'm working on a complete overhaul of the WWDC Notes community project that I took over last year. If you don't know, it's a place where members of our community share their WWDC session notes for other members in the community. This work is needed because only the notes are public, most of the projects repos (website, etc.) are not. Writing the notes is also annoying, because the website renderer doesn't support all Markdown features and you have no way to preview them locally. My plan is to fix both issues by migrating the project over to Swift-DocC. This will allow you to preview the rendering right within Xcode!

Speaking of tools I develop for the community, I just shipped a free tool that helps you manage your localizations more efficiently and finds bugs. Give it a try!

Moving on to Swift Evolution News – it's official now, Swift 6 is coming this year at WWDC! 🥳 Several of the accepted proposals I link to below have their state marked as "Implemented for Swift 6". You'll notice by the proposals currently being worked, that the main focus is ironing out rough edges of Swift Concurrency before the release of Swift 6, which will introduce a couple of extra safety checks.

If the release of a major new Swift version with breaking changes concerns you, Holly Borla from the Swift Core team is here put you at ease. In this post, she makes clear that the Swift 6 compiler will default to a Swift 5 compatibility mode, not breaking any of your code or your packages code. Only if you explicitly opt-in to Swift 6 mode, which you can do module by module, you'll get the new safety checks, warnings, and errors. This means you can adopt Swift 6 at your own pace!

Accepted Proposal Summaries

SE-0419: Swift Backtrace API

Links: 📝 Proposal  | 💬 Review  | ✅ Acceptance

On a first look, this proposal reads like one could build a crash reporting tool based on a new SymbolicatedBacktrace struct it introduces. But then it states this:

(...) the API presented here is not async-signal-safe, and it is not an appropriate tool with which to build a general purpose crash reporter. The intended use case for this functionality is the programmatic capture of backtraces during normal execution.

While backtracing and symbolication sound complex, usage can be as simple as:

import Runtime

enum SomeNamespace {
  static func doSomething() {
    do {
      try somethingThatCanFail()
    } catch {
      let bt = Backtrace.capture().symbolicated()
      if let sl = bt.frames[0].symbolInfo?.sourceLocation {
        print("Called from file \(sl.path) at line \(sl.line)")
      }
    }
  }
}

Note that you need to import Runtime to use the new backtracing capabilities. As you can see in the code above, it's easy to access the file and line of the current execution context. Think of frames like the left sidebar showing the whole call stack when you run into a breakpoint or your app crashes during debugging.

With Swift Backtrace APIs, things like debugging and performance analysis can be hugely improved because they make it much easier to diagnose our code. In complex applications, capturing a backtrace at the point of error or exception can even help us trace issues without halting the application. I can also imagine this to be super helpful for debugging & error handling for Swift on Server.

SE-0421: Generalize effect polymorphism for AsyncSequence and AsyncIteratorProtocol

Links: 📝 Proposal  | 💬 Review  | ✅ Acceptance

Not being a compiler expert, I don't fully understand this proposal. It reads similarly abstract like the title makes it sound. But I understand that there were serious problems with AsyncSequence regarding error handling (throws) and Sendable conformance. And this proposal introduces an associated Failure type and adopts my all-time favorite proposal SE-0413 Typed Throws to fix those issues, including for AsyncIteratorProtocol with a next() overload.

I think all us app developers really need to take away from this (and other accepted proposals in the recent past I didn't cover in detail) is that Apple is really focusing on getting concurrent code in Swift to a much better place with Swift 6. I'm curious to see what new consumer features or developer APIs all this work leads up to. Maybe we'll know more next month after WWDC24? Let's see!

SE-0428: Resolve DistributedActor protocols

Links: 📝 Proposal  | 💬 Review  | ✅ Acceptance

It's really hard to grasp the future impact of distributed actors in Swift, partly because the topic is inherently complicated, and partly because things are still in the works and practical usage examples are scarce. But certainly this proposal brings us another step closer to a future where if you control your own server, you might be able to get rid of the API layer entirely and just let the distributed actor system figure the communication details out for your client-server application.

Having that said, it's still not clear if this is the intended use case within Apple. I'm sure there are products or services that will profit from the work in this area, but I still struggle with a clear picture. The only things that come to my mind are uses where (part of) the processing happens on non-integrated parts. Such as the Vision Pro doing part of the processing in the battery pack in a future iteration. Or Siri processing parts of a request in the Cloud. I'm really curious to see what the future brings. I have a feeling that distributed actors might play a big role at some point.

SE-0433: Synchronous Mutual Exclusion Lock 🔒

Links: 📝 Proposal  | 💬 Review  | ✅ Acceptance

When we have shared mutable state in our apps and want to avoid race conditions that could lead to inconsistent state or unexpected results, our go-to solution in Swift should be using Actors. But actors have their own requirements, and sometimes it's not possible or reasonable to use them. In those cases…

Many Swift programs opt to use ad-hoc implementations of a mutual exclusion lock, or a mutex. (...) The main issue is that there isn't a single standardized implementation for this synchronization primitive resulting in everyone needing to roll their own.

So this proposal does exactly that, it introduces an "official" Swift Mutex type. You need to import Synchronization to use it. Then, you can write something like:

let imageCache = Mutex<[UUID: Data]>([:])

Now, whenever you want to write to the dictionary, you call .withLock like this:

imageCache.withLock { dict in
  dict[UUID()] = Data()
}

Note that a Mutex cannot be defined as var, only let works for safety reasons. Besides .withLock, there's also withLockIfAvailable which returns nil if the lock couldn't be acquired. Please be aware that a Mutex works very differently from an Actor and therefore is prone to classic problems like deadlocks. But if you know what you're doing and you need a mutex, Swift will have you covered.

Other Accepted Proposals

✉️
Don't want to miss future issues? Subscribe to the newsletter.

Proposals in Progress

Noteworthy Active Threads

Other News

On the organizational front, the Core Team has announced the formation of a "Platform Steering Group". According to its page on Swift.org their goals are to "enable the Swift language and its tools to be used in new environments" and to "drive development work that brings the Swift (...) to a variety of platforms".

And finally, don't forget to try the 2.0 release of TranslateKit to find common bugs in your localizations. Such as %lld of %lld which should be %1$lld of %2$lld. Or a missing %@ in translations. And many more – all for free! 💯

👨‍💻
Want to Connect?
Follow me on 🐦 Twitter (X), on 🧵 Threads, and 🦣 Mastodon.