First, this is an extremely well-written proposal, that explains itself well
and tries to walk a difficult tightrope. So, A+ for that.
That said, I think it needs modification before acceptance:
* I agree with Dave DeLong that @exhaustive does not actually "do anything", it
relies on library authors to do the right thing but library authors cannot be
trusted. I am not even sure Optional will continue to have its two cases based
on the track record of the swift-evolution process :-P
* I agree with Vladimir S that app developers need to be able to use
compile-time checks that they handle all the "known cases" for an arbitrary
enum (e.g. exhaustive or non-exhaustive), for example with "future" or some
other mechanism. Lack of testability does not actually concern me, but I feel
it could be addressed by allowing the assignment of Any to a non-exhaustive
enum, perhaps gated via a warning or an @testable.
I feel that a better solution to the underlying dilemma would be the following:
* As an app developer, I can use switch! or @import! to mean that I am
vendoring this SDK and the runtime library will definitely be the same library
I am linking against. So it does not matter if the library author intends to
someday add more cases – from my point of of view they are exhaustive, because
this is the library I am linking, accept no substitutes. Cases are checked at
import time, and there is a runtime exception if somebody swaps the binary for
one with "new" cases, may god have mercy on their soul
* As an app developer, in the absence of one of those opt-in mechanisms an
imported enum is assumed to be open and I must handle either a default case
(which is not compile-time checked for exhaustion) or a future case (which is).
I prefer "undefined" for "future" as a keyword because it seems to me library
authors can also remove cases, regardless of what this proposal says.
This solution is a nod to @clattner's "the difference between source packages
and binary packages that are updated outside your control (e.g. the OS, or a
dynamic library that is updated independently of your app like a 3rd party
plugin)." But he is wrong that the difference is somehow tied together with a
notion of binary and source: it is a difference between whether the library is
vendored or nonvendored, that is whether it is shipped with the application or
the OS. If it is shipped with your application, you control the updates and so
all enums can be exhaustive, if it is shipped with the OS it is updated
independently and who knows what cases will appear at runtime. But there is no
law that says I have the sourcecode for all my application's libraries or that
OS vendors only ship binaries, so I use "vendored" and "non-vendored", and
"import-time" for "compile-time" to be precise in this distinction.
As a library author, I am not sure that the @exhaustive promise is meaningful.
Unlike resilience more generally where a library author can provide some
fallback behavior for client who calls a deprecated method, there is really not
much that can be done to support older clients who are unaware of my new enum
case. I suppose we could introduce compile-time checks to prevent passing that
enum case to an older client, for example
public enum Foo {
case old
@introduced (1.1) case new
}
public final enum Fixed {
case one
@introduced (1.1) case two //error: Can't add a new case to a final enum,
drop @introduced or drop final
}
public func bar() -> Foo {
return .new //error: Not all clients support case new, use if #available or
@available
}
This sort of thing might be a justification for supporting a "final" or
"exhaustive" declaration, but the motivation in this listing is to support
library authors within their own compilation unit, rather than exposing a
signal to app developers that may or may not be reliable moving forward.
As shown in this listing, I find "final" more natural and more in the spirit of
Swift than @exhaustive.
Drew
On December 19, 2017 at 4:58:14 PM, Ted Kremenek ([email protected]) 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
Reviews are an important part of the Swift evolution process. All review
feedback should be sent to the swift-evolution mailing list at:
https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review
manager.
When replying, please try to keep the proposal link at the top of the message:
Proposal link:
https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md
...
Reply text
...
Other replies
What goes into a review of a proposal?
The goal of the review process is to improve the proposal under review through
constructive criticism and, eventually, determine the direction of Swift.
When reviewing a proposal, here are some questions to consider:
What is your evaluation of the proposal?
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?
If you have used other languages or libraries with a similar feature, how do
you feel that this proposal compares to those?
How much effort did you put into your review? A glance, a quick reading, or an
in-depth study?
Thanks,
Ted Kremenek
Review Manager
_______________________________________________
swift-evolution-announce mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution-announce
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution