Swift Evolution Monthly: January '24

Smoothing out some rough edges in Swift concurrency. System-level programming with low-level atomics. And many interesting new proposals linked!

Swift Evolution Monthly: January '24
Photo by Pablo Gentile / Unsplash

Thanks to Antoine's idea to point to other related newsletters upon subscribing, the number of people receiving this issue more than doubled within the last month, so hello and welcome on board to everyone new! 👋

January was also quite a busy month for me personally. Just as a mini recap, I shipped a huge 2.0 update to my puzzling game CrossCraft and I released a new developer app – TranslateKit – after weeks of frustration due to nonsensical rejections by the Review team. 😩 I'd love you to give both a try! The latter even launched on Product Hunt today. 👀

Note that I migrated CrossCraft to visionOS for day 1 of the Apple Vision Pro and even live-streamed the entire process here. I will upload a shorter video there. Speaking of the Vision Pro, I also released another app which I specifically developed for it to fix a flaw in the visionOS user interface. 🕓🔋

On other news, the swift.org website underwent a redesign. I really like how the crowded sidebar was replaced with a more organized top bar! Good job. 👏

Accepted Proposal Summaries

SE-0410: Low-Level Atomic Operations

Links: 📝 Proposal | 💬 Reviews: 1st, 2nd | ✅ Acceptance

This introduces low-level synchronization primitives hidden behind a module named Synchronization that you need to explicitly import to use them. App developers should probably stick to the recently introduced concurrency features like async/await, but for Swift to be successful as a systems programming language, new low-level APIs like the Atomic type introduced here are important. Some libraries also might use it internally.

SE-0416: Subtyping for keypath literals as functions

Links: 📝 Proposal | 💬 Review | ✅ Acceptance

This small proposal allows using key paths in some situations that were previously impossible. For example, the compiler is currently not able to convert the Int to an Int? (like it can in other contexts) in following code:

struct Person {
  var age: Int
}

// error: Key path value type 'Int' cannot be converted to contextual type 'Int?'
let x: (Person) -> Int? = \.age

In the future, key paths will work in more situations, including the above.

SE-0417: Task Executor Preference

Links: 📝 Proposal | 💬 Review | ✅ Acceptance

This proposal is mostly for improving the performance on event-loop based systems like network servers. It introduces a new flexible mechanism for developers to tune their applications and avoid potentially unnecessary context switching when using Swift concurrency. Read the full proposal if this affects you. Most app developers probably are good with the current defaults.

SE-0418: Inferring Sendable for methods and key path literals

📝 Proposal | 💬 Review | ✅ Acceptance

This one improves flexibility, simplicity, and ergonomics in some edge cases by inferring @Sendable in more situations surrounding functions as values and key path literals. As a quick reminder, the Sendable protocol indicates that a type is safe to be passed to other Tasks and Actors in Swift concurrency. You've probably already seen warnings in some places when using async/await. In Swift 6, some (or all?) of those warnings will become compiler errors, so it's good news that Sendability is inferred in more situations to reduce friction when entering the world of more strict safety.

SE-0420: Inheritance of actor isolation

📝 Proposal | 💬 Review | ✅ Acceptance

Here's another change that will reduce the friction around Sendable types in Swift 6. The purpose of this proposal is to allow non-Sendable data to be safely passed to functions by inheriting the isolation context. An isolated keyword (introduced in SE-0313) can be put in front of actor types alongside an #isolation expression as a default value to achieve that. As a result, functions might get declared like this:

func foo(isolation: (any Actor)? = #isolation) async

If you want to learn more about the isolated keyword, the same Antoine I mentioned at the beginning has written a great article about it.

All in all, I really like the continued effort in Swift to make concurrency work more smoothly in more situations. I have a feeling that Swift 6 isn't too far off anymore, given that we are seeing more edge cases being tackled. Maybe later this year? 🤞

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

Proposals in Progress

Noteworthy Active Threads

I love how Swift is becoming more widely usable, which I'm sure will make it a better language for app developers, too.

I'm also particularly excited about the first link in the "Active Threads" section. If I understood it correctly on a quick read, it has the potential to make away with the need to write API clients for servers altogether, hiding the client-server communication in a distributed actor. Check it out!

That was it for January. Don't forget to try CrossCraft & TranslateKit! 🌟🙏

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