[swift-evolution] [Pitch] Typed throws

Karl Wagner razielim at gmail.com
Mon Feb 20 17:34:33 CST 2017

> On 19 Feb 2017, at 21:04, Anton Zhilin <antonyzhilin at gmail.com> wrote:
> It’s expected that if you need resilience, then you will throw an “open” enum. Essentially, we pass resilience of typed throws on to those who will hopefully establish resilience of enums.
> If you prefer separate error types, then declare a base protocol for all your error types and throw a protocol existential. You won’t even need default case in switches, if closed protocols make it into the language.
> I don’t like any solution that is based on comments. I think that compiler should always ignore comments.

Open enums can only add cases, not remove them. That means that new versions of a function will similarly only be able to add errors, and won’t be able to communicate that certain errors are no longer thrown. Protocols aren’t a solution, because you will need to write verbose conformances for all of your Error types.

Let me put this in another (perhaps more palatable) way. Forget comments, let’s say its part of some hidden metadata:

- The compiler lists every error which can be thrown by a function (it’s easily able to do that)
- Rather than making this part of the signature, the signature only says “throws an Error” and the actual Error list is written somewhere in the module as documentation/metadata.

Here’s why it’s so good:

- It’s completely free (you don’t write anything). The compiler generates everything for you.
- It’s **completely optional**: it won’t make your structure your Errors in a way that's less usable in a type-system sense for clients who don’t care about exhaustive catching.
- Exhaustive catching within your own module for free (you can omit a catch-all, the compiler won’t complain)

It’s good for resiliency, too:

- Non-resilient functions always reserve the right to throw new Errors in later versions. No system will get exhaustive catching for them anyway.
- If you stop throwing a specific Error, nothing breaks - it simply vanishes from the documentation/metadata. The compiler can simply warn about the redundant catch.
- Resilient (@versioned) functions can still offer exhaustive catching if we want to offer that. We might decide to make that opt-in/opt-out, because it would mean they would be limited to removing Errors, and never adding new ones.
—> As with any ABI promise, we will trap or it will be UB if you break the contract. We couldn’t validate it when compiling, but theoretically a validator could be built which compared two library versions.

- Karl

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170221/f4477c29/attachment-0001.html>

More information about the swift-evolution mailing list