Tuesday, November 28, 2023

Swift Proposal: Typed Throws

SE-0413:

Swift is known for being explicit about semantics and using types to communicate constraints that apply to specific APIs. From that perspective, the fact that all thrown errors are of type any Error feels like an outlier. However, it reflects the view laid out in the original error handling rationale that errors are generally propagated and rendered, but rarely handled exhaustively, and are prone to changing over time in a way that types are not.

[…]

The loss of information between types like Result and Task and the language’s error-handling system provides partial motivation for the introduction of typed throws, and is discussed further below.

Typed throws also provides benefits in places where clients need to exhaustively handle errors. For this to make sense, the set of potential failure conditions must be relatively fixed, either because they come from the same module or package as the clients, or because they come from a library that is effectively standalone and unlikely to evolve to (e.g.) pass through an error from another lower-level library. Typed throws also provides benefits in generic code that will propagate errors from its arguments, but never generate errors itself, as a more flexible alternative to the existing rethrows. Finally, typed throws also open up the potential for more efficient code, because they avoid the overhead associated with existential types (any Error).

Even with the introduction of typed throws into Swift, the existing (untyped) throws remains the better default error-handling mechanism for most Swift code.

Rob Napier (2016):

I was an early proponent of typed errors in Swift. This is how the Swift team convinced me I was wrong.

Strongly typed errors are fragile in ways that can lead to poor API evolution. If the API promises to throw only one of precisely 3 errors, then when a fourth error condition arises in a later release, I have a choice: I bury it somehow in the existing 3, or I force every caller to rewrite their error handling code to deal with it. Since it wasn’t in the original 3, it probably isn’t a very common condition, and this puts strong pressure on APIs not to expand their list of errors, particularly once a framework has extensive use over a long time (think: Foundation).

Of course with open enums, we can avoid that, but an open enum achieves none of the goals of a strongly typed error. It is basically an untyped error again because you still need a “default.”

[…]

Last of all, for strongly typed errors to be of much use, Foundation would need to throw them since it is the largest producer of errors in the system.

Previously:

Update (2024-02-23): Donny Wals:

At the time of writing this post SE-0413 has been accepted but not yet implemented.

[…]

Personally, I think typed throws are a nice feature but that we won’t see them used that much.

The fact that we can only throw a single type combined with having to try calls in a do block erasing our error back to any Error means that we’ll still be doing a bunch of switching and inspecting to see which error was thrown exactly, and how we should handle that thrown error.

Update (2025-09-03): Dave DeLong:

One of these days I’m going to get so fed up with @swiftlang never actually finishing feature implementations and switch to something else.

[…]

Today’s woe is that @swiftlang’s “typed throws” feature was only half-implemented. It only works in the absolute happiest of paths. Any deviation from that and the compiler refuses to type-check anything and the entire feature is entirely worthless.

But of course if you ask, you’ll get told “it’s done because the all the features of the evolution were implemented and everything else is a Future Direction”.

Dave DeLong:

it kind of works. But there are glaring holes in the type checker where the error type is lost because that bit hasn’t been implemented yet. So even though everything is fully typed to a single error type, the compiler still reverts to “any Error”, completely negating the entire point of using the feature.

1 Comment RSS · Twitter · Mastodon


Apple implemented something in a half-assed way!? I’m shocked!
The fact DeLong is shocked is hilarious, considering he used to work there, twice!, until a year ago. He should know better.

Leave a Comment