> On Dec 19, 2017, at 2:58 PM, Ted Kremenek via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
> The review of "SE 0192 - Non-Exhaustive Enums" begins now and runs through 
> January 3, 2018.
> 
> The proposal is available here:
> 
> https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md
>  
> <https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md>
> What is your evaluation of the proposal?
> 
I was going to say -100 without future, +1 with, but other arguments on this 
thread have put me on the fence to mildly against, so -100 without future, -ε 
with.


In the proposal, there is the following text:
> The consequences of losing exhaustiveness checking for non-exhaustive enums 
> are discussed in the "Alternatives considered" section at the end of this 
> proposal.
> 
> A number of pre-reviewers have been concerned about the loss of 
> exhaustiveness checking and the subsequent difficulty in updating to a new 
> version of a dependency. In the original swift-evolution thread, Vladimir S. 
> describes the concerning scenario 
> <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20171002/040053.html>
>  in detail.
I find it deeply disturbing that this scenario is acknowledged as "concerning" 
and yet ignored without justification in the proposal proper, and in the 
"alternatives" dismissed solely based on a baseless assumption—that the 
situation will be "uncommon." Even if it were an uncommon case, the negative 
impact is still dire enough and without a good workaround that I'd argue 
strongly that the concern be addressed properly.

The justification put forward to reject a `future` case is that "The 
expectation is that switches over non-exhaustive enums are uncommon." However, 
there is no evidence to support that assertion, and there are a huge number of 
enums in even just Apple's frameworks that people reasonably can, and in some 
cases really should, switch over. Go through any of the iOS frameworks and find 
authorization enums and delegates with enums in a callback, and you're likely 
to find some that it makes sense for a client to switch over. Just a few off 
the top of my head that I have personally switched on:

CoreBluetooth
- CBManagerState
- CBPeripheralManagerAuthorizationStatus
- CBPeripheralState
CoreLocation
- CLAuthorizationStatus
- CLActivityType
CoreData
- NSFetchedResultsChangeType
MessageUI
- MessageComposeResult
UIKit
- UITableViewCellEditingStyle

Every framework that requires user permission has its own authorization enum, 
many have an additional state enum, and for most delegate callbacks with an 
enum argument it's often a good idea to switch over the cases.

As a real-life example above and beyond the one referenced above, In the fairly 
small codebase I'm working in at the moment, I count a bit over 12klocs, 80-ish 
switches, and 6 switches that would need a `future` case (non-exhaustive, from 
Apple frameworks). That's about one per 2klocs, It probably wouldn't scale 
linearly in larger projects, but just their prevalence in the apple frameworks 
as I pointed out above would suggest it does grow significantly.

The extra onus on project authors required by not including a future case for 
those cases would make upgrading libraries and iOS versions incredibly 
difficult and error-prone. To ensure correctness, you would have to go over 
every single switch in your app, figure out the type it's switching on, and if 
the type is external and nonexhaustive, check that there are no new cases. Even 
if this is "not expected to be the common case," omitting the `future` means 
you have to either keep track of where all your relevant switch statements are 
and check them on every upgrade, go through and evaluate every switch statement 
to figure out whether you need to check for extra cases, or go through the API 
diff, find any added enum cases, and find every switch in your codebase that 
switches on them. All three options are dangerously error-prone and 
unacceptable.

In summary, failing to include a future case but requiring default instead 
would place an unacceptable burden on every nontrivial project every time a 
library is upgraded and (and I don't say this lightly) would almost certainly 
be the biggest mistake the Swift community has ever made.

There is an existing implementation along with the PR, so has anyone tried this 
change a project of significant size that uses a variety of Apple frameworks? 
How many `default`s did you have to put in that should be `future`, and how 
would you feel about having to find all those places again and any more that 
may be put in in a year or two *without* compiler checking?
> Is the problem being addressed significant enough to warrant a change to 
> Swift?
> 
The problem needs to be addressed, certainly.
> Does this proposal fit well with the feel and direction of Swift?
> 
With future, sure. Without, absolutely not. As demonstrated and even 
acknowledged but dismissed without justification, it introduces an enormous 
issue with compile-time safety.
> If you have used other languages or libraries with a similar feature, how do 
> you feel that this proposal compares to those?
> 
N/a
> How much effort did you put into your review? A glance, a quick reading, or 
> an in-depth study?
> 
I kept maybe half an eye on the original thread, but read the proposal and 
other posts in this review thread thoroughly.
> Thanks,
> Ted Kremenek
> Review Manager
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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

Reply via email to