> On 19 Feb 2017, at 21:04, Anton Zhilin <antonyzhi...@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

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to