[swift-evolution] The Non-Exhaustive Enums proposal kills one of Swift's top features - change proposal

Jordan Rose jordan_rose at apple.com
Thu Dec 21 12:33:00 CST 2017


[Proposal: https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md]

> On Dec 21, 2017, at 09:49, Ignacio Soto via swift-evolution <swift-evolution at swift.org> wrote:
> 
> I think I speak for the entire Swift community when I say that Swift's enums, together with the ability to switch over them exhaustively and having compile-time guarantees, is one of the best features in Swift. I'm regularly annoyed by this when writing other languages like Java and JS (default: throw new IllegalArgumentException();)
> 
> Now, that's not to say I don't understand why this proposal is necessary. I totally get it, and the existing decisions make a lot of sense to me. But I'd like us to introduce this while maintaining the ability to guarantee exhaustive switch statements, no matter how the enum was defined.
> 
> Example: imagine a theoretical SampleKit defines:
> public enum E {
> case A
> case B
> }
> 
> It's implicitly non-exhaustive, possibly because the author was not aware of the default (which would likely happen often), or possibly because they made a conscious decision, as they expect to expand the cases in the future.
> 
> In my app, I use SampleKit and decide that I want to make sure I handle all cases:
> 
> switch e {
> case A: break
> case B: break
> default: break // This becomes necessary
> }
> 
> As the proposal stands right now, I'm forced to handle any future cases. That's fine. What's not fine in my opinion, is that in doing so I lose the ability to keep this exhaustiveness moving forward. If I update SampleKit to v2.0, I want to know at compile-time if there are new cases I need to be aware of (instead of going to some generic handling path). Instead, I’m left in the same place I would in other languages like Java or JS:
> 
> // No error :(
> switch e {
> case A: break
> case B: break
> default: break
> }
> 
> Proposed Solution
> 
> What I’m proposing is that we introduce a new keyword, unknown (or a better name), that serves as a way to handle cases that aren’t yet known, but not those that are.
> 
> // Error: missing case C
> switch e {
> case A: break
> case B: break
> unknown: break // Would handle future cases
> }
> 
> With this, you shouldn’t be able to use default AND unknown at the same time, as default implicitly includes unknown.
> 
> Thanks for reading, and I hope you can consider this change (or some variation of it).

Hi, Nacho. This is discussed in the proposal as "'future' cases" under "Alternatives considered". The main blocker was that such a case becomes untestable (see also "Testing invalid cases"). That didn't seem like an acceptable state of affairs to me or to the people I had originally discussed the proposal with, but maybe the community feels differently?

I would love if someone could think of something I haven't yet; by no means do I think I'm the only one who can have ideas in this space.

Jordan
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20171221/903dbec6/attachment.html>


More information about the swift-evolution mailing list