UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

What made Result finally appear in Swift?

Recorded – watch the full episode on YouTube.

We're glad to see Result in Swift 5, but what took so long to add it and what actually made it happen in the end?

Chris Lattner: Well, there's this amazing new research paper on Result that was published in 2019 and so we realized when reading that paper it was a good... just kidding. Okay, coming back to social problems. It's not just about technical things. Design is hard. Social differences are difficult to work through. To me, it was very clear early on that Result was a very important thing to have as part of the language. I think we discussed adding it with Swift 2. So Swift 2 is when error handling came in.

“One of the controversial and undecided things about Swift error handling is that errors in Swift are not typed."

I think that at the time, Swift 2 was also a very hot mess and fast ride towards its own release because it was a very large scope release, and so I think that Result just got pushed out of that release and so it just missed that. Now when error handling came in, that took some time for the community to adopt it, understand it, get implementation experience and so there's some early discussion about, “oh, well, maybe we don't need Result.”

I think there are other people who were arguing, "We do need Result because try and catch are one thing but when you need to shuttle something across threads or you want to do these other things, you need a convenient way to express this." And I thought that was pretty unambiguous because people were doing it all the time.

So there was a discussion about how we do this, and here's where you get to the social challenge. One of the controversial and undecided things about Swift’s error handling is that errors in Swift are not typed. Instead, they type erase to Error and that is absolutely the right thing to do for large-scale frameworks, like UIKit or AppKit – Apple-scale, long-term evolution frameworks, because many of us that have worked on Java and similar things like that see the problems that come about with very specifically typed errors when you do library evolution. And so you want to add networking into the middle of a thing, okay, well now I can start producing network errors and the caller was never prepared for that. So now what do you do? There's lots of bad history and lots of damage that many people are facing this.

"Today Swift does not have typed errors. However, there are other domains, and Swift attempts to solve for multiple different domains where you do know exactly what kind of area you're throwing."

And so today Swift does not have typed errors. However, there are other domains, and Swift attempts to solve for multiple different domains where you do know exactly what kind of area you're throwing. Well, let's pick a simple example, like to Unix syscalls. There is an ironclad guarantee that open() will only return certain classes of errors. You cannot add new things to that, you just cannot, that's the thing.

There are also use cases for error handling where you're using it more as a control flow mechanism than as propagating a high-level error from a user down through my code. In those cases, again, it's not about reflecting user-visible, localized messages, it's about how do I reflect the fact that I have normal control and unusual control.

And so in these cases, I think the typed errors are absolutely appropriate, and sure, there's an opportunity for misuse and like, "Oh my god, we may fall into the typing all the things and end up in Java framework land." But I think that the odds of that are extremely low and I'm not personally concerned about that.

And so a lot of the discussion in Result came down to this inherent tension. Do we have typed errors or not? Are we going to have typed errors? Because that's one of the things that is an open point of evolution is, we could add typed errors at any point in time, there's a natural way to do that, and it would be very clean and consistent. And so there's this question of resource allocation prioritization.

"We wanted Result to be consistent and contiguous with the error handling approach, but we don't know what your handling approach ultimately will be."

On the one hand, somebody has to be willing to implement it, combined with, then, if somebody is willing to implement it, is it a good thing? Would we say no? And so with Result, basically, a lot of that discussion came down to, fine, we may or may not do this with throws.

So what should we do with the Result? We wanted Result to be consistent and contiguous with the error handling approach, but we don't know what your handling approach ultimately will be. And so, that was a lot of that discussion.

And so, for what it’s worth, I'm very happy with how Result ended up. So with Result, you can type the error. And so you can type it to Error, so you can type erase it yourself, if you want to. And you can be very contiguous with the existing error handling approach. And so I think that's a good design.

But also Result gets used for more than just throws. It gets used for lots of things, asynchronous things for foreign APIs, other stuff like that. And so I think that it's clearly the right thing to do.

So I don't know if that answers the question, but I also think that getting typed errors into Swift would be a very, very, very good thing for, admittedly, a narrow class of users that are important, but are maybe not the most important thing right now.

Paul Hudson: Well, as you say, there's an easy way of getting in it pretty much. You have throws right now, you'd leave that in place, leave it completely untyped, but also throws SomeError. And it becomes optional if you know for your particular case, bang, it works, great. But it leaves it... or your UIKit app, like you said, could just carry on cruising along happily without those things.

"When you throw an error in Swift, one of the things we put great effort into is making it so that throws in Swift is not like exceptions in Java or C++. Producing errors are actually relatively efficient."

Chris Lattner: Yes, and I mean, the advantage of type throws is really twofold. One is, you get the type safety. So when you have your cash clause, you you can enumerate the different enum cases or whatever it is that you're cashing, things like that. You get specificity in your errors. And if you know you're only going to throw one thing, you can say that.

The other thing is efficiency. And so when you throw an error in Swift, one of the things we put great effort into is making it so that throws in Swift is not like exceptions in Java or C++. Producing errors are actually relatively efficient.

But because that error gets type erased to the Error protocol, that means that if the value you're throwing is above a certain size, it has to be boxed under the heap. And so you get an allocation for that error that you produce. And for normal code, this is not a problem at all. This is like so much in the noise, it's not even worth considering, but there are classes of code where you care about deterministic performance and things like this, where that's not ideal.

This transcript was recorded as part of Swiftly Speaking. You can watch the full original episode on YouTube, or subscribe to the audio version on Apple Podcasts.

Listen on Apple Podcasts

BUILD THE ULTIMATE PORTFOLIO APP Most Swift tutorials help you solve one specific problem, but in my Ultimate Portfolio App series I show you how to get all the best practices into a single app: architecture, testing, performance, accessibility, localization, project organization, and so much more, all while building a SwiftUI app that works on iOS, macOS and watchOS.

Get it on Hacking with Swift+

Sponsor Hacking with Swift and reach the world's largest Swift community!

BUY OUR BOOKS
Buy Pro Swift Buy Pro SwiftUI Buy Swift Design Patterns Buy Testing Swift Buy Hacking with iOS Buy Swift Coding Challenges Buy Swift on Sundays Volume One Buy Server-Side Swift Buy Advanced iOS Volume One Buy Advanced iOS Volume Two Buy Advanced iOS Volume Three Buy Hacking with watchOS Buy Hacking with tvOS Buy Hacking with macOS Buy Dive Into SpriteKit Buy Swift in Sixty Seconds Buy Objective-C for Swift Developers Buy Beyond Code

Was this page useful? Let us know!

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.