Here are 3 cool new features of Swift 5.9 🤩

Hi 👋

I’m very excited about this week because I’m attending a conference called Swift Island, where I’ll be teaching a workshop on the new features of Swift 5.9!

(and actually, at the time this email will be sent I will probably be right in the middle of boarding my plane to Amsterdam 🛫)

Since I’ve been working quite a lot with Swift 5.9 these past few days, I figured it would also make the perfect topic for this week’s email!

But before we start, I have a big thank you to the sponsor of this email: Bitrise 🤖


Advertisement

Join the Mobile DevOps Summit 2023 on Oct 4-5

A two-day, free event with 40+ workshops and sessions brought to you by 50+ industry-leading speakers from eBay, Reddit, AWS and more.

Learn from real-world examples of successful Mobile DevOps implementations!

👉 Check out the speaker list 👈


Sponsors like Bitrise really help me grow my content creation, so if you have time please make sure to have a look at the event they’re organizing: it’s a direct support to my content creation ☺️


You’re probably aware that Apple’s September keynote will be taking place on the 12th.

This means that it is now a matter of days before the official release of Xcode 15, and along with it the release of Swift 5.9!

So how about we prepare for it by going over 3 features that this new version of Swift will add to the language?

#01 – using if and switch as expressions

Until Swift 5.9, the keywords if and switch could only be used as statements.

This meant that it wasn’t possible to directly assign the result of an if or a switch to a variable or to pass it as an argument.

Of course there were tricks to go around this limitation: you could wrap the if or the switch into a closure that you would then immediately call.

Or worse, you could nest ternary expressions:

In Swift 5.9, this limitation has been lifted: if and switch can now be used as expressions!

This means that these awful nested ternary expressions can now be replaced by much more readable if conditions:

Even better, this new feature also works with conditional binding:

#02 – Parameter Packs

If you’ve ever had to write code that needed to handle an unknown number of generic types, you’ve probably learned the hard way that Swift didn’t offer support for variadic generics.

And that the best you could do would be to implement multiple overloads, that would handle up to a certain number of generic arguments:

And even though this approach looks a bit ridiculous, major first party frameworks like SwiftUI and Combine used to rely on this trick!

Unfortunately, it has a major drawback: since you can’t implement an infinite number of overloads, there will always be a limit on the number of arguments your function can handle:

Have you ever wondered why a SwiftUI view couldn’t support more than 10 child views? Now you know the answer!

But if you open Xcode 15 and try to add 11 child to a SwiftUI view, you will notice that this limitation is now gone 😯

This is thanks to a new feature of Swift 5.9 called Parameter Packs:

Using the keyword each, we are able to declare a Parameter Pack.

And then, through the keyword repeat we are able to use this Parameter Pack, for instance to declare the arguments of a function or to define a tuple type:

Thanks to this new syntax, our function evaluate() is now able to handle any arbitrary number of arguments 👌

However be careful: there’s a reason why this feature is called Parameter Packs and not Variadic Generics!

It’s because how you handle a Parameter Pack is still a bit limited: for instance it’s not yet possible to iterate over each individual argument the function will receive.

#03 – Macros

Back in 2019, Swift had introduced Property Wrappers, which enabled us to nicely encapsulate a lot of boilerplate code.

This year, the language goes even further with the introduction of Macros, that are nothing less than small compiler plugins capable of generating code on your behalf.

Here’s the typical kind of boilerplate code that a macro can generate for you: defining a convenience computed property for each of the cases in an enum.

In Swift 5.9 you can remove this boilerplate code and instead implement a macro called @CaseDetection:

At compile time, this macro will then be expanded by the Swift compiler in order to produce the generated code:

This example already hints at how powerful macros can be, but if you want to see a really impressive use case, look no further than SwiftUI.

Thanks to macros, all the complex code that used to be required for your views to correctly observe the state of your app…

…has been greatly simplified, to the point that in this example you now just need to use the macro @Observable once:

Actually, this code is not only simpler but also more performant: thanks to macros, SwiftUI is now able to precisely keep track of which properties are actually read by a view and which are not!

If you want to see examples of how macros can be implemented, you can check out this repository, where you’ll find, among others, the code for the macros @CaseDetection and @Observable.

Conclusion

That’s it: these were the 3 new features of Swift 5.9 in wanted to introduce you to!

If you want to learn more about what’s new in Swift 5.9, here are a couple resources I can recommend:

That’s all for this email, thanks for reading it!

If you’ve enjoyed it, feel free to forward it
to your friends and colleagues 🙌

I wish you an amazing week!

❤️

Previous
Previous

Bad practice: capturing self in a nested closure

Next
Next

Bad practice: using an unsafe continuation