[swift-evolution] [swift-evolution-announce] [Review] SE 0192 - Non-Exhaustive Enums

Brent Royal-Gordon brent at architechies.com
Wed Dec 20 04:39:57 CST 2017

> On Dec 20, 2017, at 1:00 AM, Sebastian Hagedorn via swift-evolution <swift-evolution at swift.org> wrote:
>>  The expectation is that switches over non-exhaustive enums are uncommon.
> Basically every time I interact with an enum, I switch over it, to make sure I don’t forget anything, and to make sure I reconsider my code if the library changes. Since most SDK enums will become non-exhaustive, this is the 99% case for me.

Is that typical of your interactions with, say, `UIViewAnimationTransition`?

There are three categories of enums in the SDK:

	1) Those which you switch over and which are inherently exhaustive. For example, `ComparisonResult` will never, ever have a case besides `orderedAscending`, `orderedSame`, and `orderedDescending`. All possible values fit into one of these three categories (other than those for which comparison is not a valid operation). You want an exhaustive switch for these.

	2) Those which you switch over but which could have cases added in the future. For example, `SKPaymentTransactionState` (representing the state of an in-app purchase) may sometimes need additional cases; one was already added in iOS 8 for a parental permission feature. You want a nonexhaustive switch for these, with a `default` clause containing some fallback behavior (like skipping the associated entry or showing an error message).

	3) Those which you almost never switch over at all; they are simply used as opaque inputs to APIs in the same framework. For example, very few pieces of code ever need to examine or use a `UIViewAnimationTransition`; they just need to pass one into the proper UIKit animation APIs. (Error types are another example—you should catch specific errors you know you want to handle specially, but you should never imagine that you have thought of all possible errors.) You basically don't care about the switch behavior of these enums; the compiler could even ban switching over them and you would probably never notice.

Category 1 enums should be exhaustive; category 2 and 3 should be nonexhaustive. So the question is, do category 1 enums outnumber category 2 and 3? You seem to suggest that they do, but I very much doubt that. My suspicion is that category 3 is the most common, followed by category 2, with category 1 bringing up the rear. The authors of the proposal say they surveyed Foundation enums to test this theory:

> To see how this distinction will play out in practice, I investigated the public headers of Foundation in the macOS SDK. Out of all 60 or so NS_ENUMs in Foundation, only 6 of them are clearly exhaustive:
> 	• ComparisonResult
> 	• NSKeyValueChange / NSKeyValueSetMutationKind
> 	• NSRectEdge
> 	• FileManager.URLRelationship
> 	• maybe Decimal.CalculationError
> ...with a handful more that could go either way, such as Stream.Status. This demonstrates that there is a clear default for public enums, at least in Objective-C.

Maybe a survey of another library like Alamofire would show different results; if you think it would, by all means feel free to demonstrate it.

Having said that, I too think that `future` or `unknown` is a good idea, and I think we should strongly consider adding it. Doing so would restore many of the correctness benefits of exhaustiveness checking to nonexhaustive enums, significantly reducing the painful parts of this feature.

Brent Royal-Gordon

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20171220/37f49540/attachment.html>

More information about the swift-evolution mailing list