[swift-evolution] [Review] SE 0192 - Non-Exhaustive Enums
matthew at anandabits.com
Sun Dec 31 14:14:01 CST 2017
I have been busy over the holidays and have been considering the arguments in this thread so my review is late in coming.
> What is your evaluation of the proposal?
I agree that we need a solution to the problem described. I also agree that non-exhaustive is most in keeping with the overall design of Swift at module boundaries. However, I believe this proposal should be modified before being accepted
My primary concern (shard with many others) is that this proposal takes away an important tool of exhaustiveness checking in cases where we need to switch over an enum vended by a library which was not declared exhaustive.
This is likely to be a relatively rare need mostly encountered by 3rd party libraries but it will happen. When it does happen it would be really unfortunate to be forced to use a `default` clause rather than something like a `future` clause which will produce an error when compiled against an SDK where the enum includes cases that are not covered. I can imagine cases where this catch-all case would need to do something other than abort the program so I do not like the `switch!` suggestion that has been discussed. The programmer should still be responsible for determining the behavior of unknown cases.
I find the argument of untestable code to be completely unconvincing. As has been noted several times in this thread, when all known cases are covered in a switch statement the code is equally untestable whether the “other" pattern is spelled `default` or `future`. There has been some discussion of finding a way for the compiler to support an extra test-only value somehow. A tool like this could be quite useful regardless of how the “other” pattern is spelled but the presence or absence of this tool should not influence the decision to include “future” or not.
While library authors have a legitimate need to reserve the right to introduce new cases for some enums this need can be met without taking away a useful tool for generating static compiler errors when code does not align with intent (in this case, the intent being to cover all known cases). Switch statements working with these kinds of enums should be required to cover unknown cases but should be able to do so while still being statically checked with regards to known cases.
People are going to write these kinds of switch statements whether the language helps them out or not. Instead of taking a moral standpoint that says “that is bad, don’t do it” the language should continue to provide assistance to the degree it can. If the core team remains unconvinced about use cases for these kinds of "pseudo-exhaustive” switches I suggest a brief extension to the review with a specific request for example use cases. I believe several good examples could be quickly identified in existing open source libraries.
A secondary concern I have is the @exhaustive keyword itself. I strongly believe Swift will be better suited by a more general keyword that is also applicable in other contexts.
I authored earlier discussions about how exhaustiveness could fit into the access control system. This is discussed as an alternative under “closed” and “open”. I think “closed” as a “greater than public” availability with respect to switch statements is perfectly sensible. In this design the access control hierarchy would have two branches in different directions that are both "greater than public”. This direction had some proponents but didn’t appear to gain traction with the core team. In case the core team discusses this option I do still prefer it.
Another direction that has been discussed in this thread is to use a keyword that is shared with fixed layout structs. Both of these feel like better options than a special case, enum-only attribute. On the other hand, this is a relatively minor concern.
> Is the problem being addressed significant enough to warrant a change to Swift?
> Does this proposal fit well with the feel and direction of Swift?
For the most part. However, it does introduce a special case attribute specifically for enums. I would prefer if we try to avoid that and believe it is in keeping with the direction of Swift to try and avoid these.
> If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
I have not worked with a language that supported both exhaustive and non-exhaustive enums.
> How much effort did you put into your review? A glance, a quick reading, or an in-depth study?
In-depth study of the proposal and all of the threads on the list.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the swift-evolution