Enums and Source Compatibility

Jordan,

Do you have any other thoughts about the ongoing discussion here, especially regarding Chris’ comments? As you’re the one pushing this forward, I’d really like to know what your thoughts are regarding this?

- Rod

Sorry, I got distracted by other tasks! Both the discussion here and within Apple has moved towards making "non-exhaustive" the default, which, to be honest, I too think is the best design. I'll update the proposal today to reflect that, though I still want to keep both the "nonexhaustive" and "exhaustive" keywords for Swift 4 compatibility for now (or whatever we end up naming them). The compatibility design is a little less ambitious than Brent's; as currently proposed, Swift 4 mode continues to default to 'exhaustive' all the time, even in the actual Swift 5 release.

I still want to respond to Brent's points directly, but I think you and Vladimir have done a good job discussing them already. I'll send out the updated proposal tomorrow, after I have a little more time to think about #invalid.

Thanks for putting time into this!
Jordan

···

On Sep 9, 2017, at 17:34, Rod Brown <rodney.brown6@icloud.com> wrote:

Jordan,

Do you have any other thoughts about the ongoing discussion here, especially regarding Chris’ comments? As you’re the one pushing this forward, I’d really like to know what your thoughts are regarding this?

- Rod

Proposal updated, same URL: https://github.com/jrose-apple/swift-evolution/blob/non-exhaustive-enums/proposals/nnnn-non-exhaustive-enums.md\.

Thanks again for all the feedback so far, everyone!
Jordan

···

On Sep 12, 2017, at 17:55, Jordan Rose via swift-evolution <swift-evolution@swift.org> wrote:

Sorry, I got distracted by other tasks! Both the discussion here and within Apple has moved towards making "non-exhaustive" the default, which, to be honest, I too think is the best design. I'll update the proposal today to reflect that, though I still want to keep both the "nonexhaustive" and "exhaustive" keywords for Swift 4 compatibility for now (or whatever we end up naming them). The compatibility design is a little less ambitious than Brent's; as currently proposed, Swift 4 mode continues to default to 'exhaustive' all the time, even in the actual Swift 5 release.

I still want to respond to Brent's points directly, but I think you and Vladimir have done a good job discussing them already. I'll send out the updated proposal tomorrow, after I have a little more time to think about #invalid.

Thanks for putting time into this!
Jordan

On Sep 9, 2017, at 17:34, Rod Brown <rodney.brown6@icloud.com> wrote:

Jordan,

Do you have any other thoughts about the ongoing discussion here, especially regarding Chris’ comments? As you’re the one pushing this forward, I’d really like to know what your thoughts are regarding this?

- Rod

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

Hi Jordan,

I think this is a great update to the proposal. The scope is small, which is good, and it clearly speaks about it’s reasoning about some of the concerns some people have.

A big thumbs up from me! :+1:

- Rod

···

On 14 Sep 2017, at 5:16 am, Jordan Rose via swift-evolution <swift-evolution@swift.org> wrote:

Proposal updated, same URL: https://github.com/jrose-apple/swift-evolution/blob/non-exhaustive-enums/proposals/nnnn-non-exhaustive-enums.md\.

Thanks again for all the feedback so far, everyone!
Jordan

On Sep 12, 2017, at 17:55, Jordan Rose via swift-evolution <swift-evolution@swift.org> wrote:

Sorry, I got distracted by other tasks! Both the discussion here and within Apple has moved towards making "non-exhaustive" the default, which, to be honest, I too think is the best design. I'll update the proposal today to reflect that, though I still want to keep both the "nonexhaustive" and "exhaustive" keywords for Swift 4 compatibility for now (or whatever we end up naming them). The compatibility design is a little less ambitious than Brent's; as currently proposed, Swift 4 mode continues to default to 'exhaustive' all the time, even in the actual Swift 5 release.

I still want to respond to Brent's points directly, but I think you and Vladimir have done a good job discussing them already. I'll send out the updated proposal tomorrow, after I have a little more time to think about #invalid.

Thanks for putting time into this!
Jordan

On Sep 9, 2017, at 17:34, Rod Brown <rodney.brown6@icloud.com> wrote:

Jordan,

Do you have any other thoughts about the ongoing discussion here, especially regarding Chris’ comments? As you’re the one pushing this forward, I’d really like to know what your thoughts are regarding this?

- Rod

_______________________________________________
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

Hi Jordan,

I’d appreciate it if you could look at the comments I made upthread and respond to them. Thanks.

-Chris

···

On Sep 13, 2017, at 12:17 PM, Jordan Rose via swift-evolution <swift-evolution@swift.org> wrote:

Proposal updated, same URL: https://github.com/jrose-apple/swift-evolution/blob/non-exhaustive-enums/proposals/nnnn-non-exhaustive-enums.md\.

Thanks again for all the feedback so far, everyone!

I’m still very much bothered by having 2 new keywords. I would really prefer the following plan:

Exhaustive by default in Swift 4
No new keyword in Swift 4 to change that behaviour
Non-exhaustive by default outside the module in Swift 5
exhaustive keyword to change the default behaviour

Like that, we don’t need nonexhaustive.

Thoughts?
David.

···

On 13 Sep 2017, at 21:16, Jordan Rose via swift-evolution <swift-evolution@swift.org> wrote:

Proposal updated, same URL: https://github.com/jrose-apple/swift-evolution/blob/non-exhaustive-enums/proposals/nnnn-non-exhaustive-enums.md\.

Thanks again for all the feedback so far, everyone!
Jordan

On Sep 12, 2017, at 17:55, Jordan Rose via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Sorry, I got distracted by other tasks! Both the discussion here and within Apple has moved towards making "non-exhaustive" the default, which, to be honest, I too think is the best design. I'll update the proposal today to reflect that, though I still want to keep both the "nonexhaustive" and "exhaustive" keywords for Swift 4 compatibility for now (or whatever we end up naming them). The compatibility design is a little less ambitious than Brent's; as currently proposed, Swift 4 mode continues to default to 'exhaustive' all the time, even in the actual Swift 5 release.

I still want to respond to Brent's points directly, but I think you and Vladimir have done a good job discussing them already. I'll send out the updated proposal tomorrow, after I have a little more time to think about #invalid.

Thanks for putting time into this!
Jordan

On Sep 9, 2017, at 17:34, Rod Brown <rodney.brown6@icloud.com <mailto:rodney.brown6@icloud.com>> wrote:

Jordan,

Do you have any other thoughts about the ongoing discussion here, especially regarding Chris’ comments? As you’re the one pushing this forward, I’d really like to know what your thoughts are regarding this?

- Rod

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto: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

In general, I agree with everything in the proposal.

I’d like to propose these alternative extensions for clients:

1) As a client of an enum, I’d like to know in the future when a new value has been added to an enum, since I may have to do something about it. How about adding the “exhaustive” keyword to be used in the switch statement? Like

exhaustive switch excuse {
    case eatenByPet:
        // …
    case thoughtItWasDueNextWeek:
        // …
    default:
        // …
}

If exhaustive is used, there would be a warning if all cases aren’t covered *even though default exists*. This means that I as the client thought I had everything covered when I wrote this code.

As already mentioned, this makes the default case un-testable, which brings me to

2) All non-exhaustive enums should have the pseudo value “default” that can be used just like a regular value. This would allow you to write code like:

teacher.failedToHandInHomework(excuse: .default)

which would allow you to trip the default case in any code you may write.

-Kenny

···

On Sep 13, 2017, at 12:17 PM, Jordan Rose via swift-evolution <swift-evolution@swift.org> wrote:

Proposal updated, same URL: https://github.com/jrose-apple/swift-evolution/blob/non-exhaustive-enums/proposals/nnnn-non-exhaustive-enums.md\.

Thanks again for all the feedback so far, everyone!
Jordan

On Sep 12, 2017, at 17:55, Jordan Rose via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Sorry, I got distracted by other tasks! Both the discussion here and within Apple has moved towards making "non-exhaustive" the default, which, to be honest, I too think is the best design. I'll update the proposal today to reflect that, though I still want to keep both the "nonexhaustive" and "exhaustive" keywords for Swift 4 compatibility for now (or whatever we end up naming them). The compatibility design is a little less ambitious than Brent's; as currently proposed, Swift 4 mode continues to default to 'exhaustive' all the time, even in the actual Swift 5 release.

I still want to respond to Brent's points directly, but I think you and Vladimir have done a good job discussing them already. I'll send out the updated proposal tomorrow, after I have a little more time to think about #invalid.

Thanks for putting time into this!
Jordan

On Sep 9, 2017, at 17:34, Rod Brown <rodney.brown6@icloud.com <mailto:rodney.brown6@icloud.com>> wrote:

Jordan,

Do you have any other thoughts about the ongoing discussion here, especially regarding Chris’ comments? As you’re the one pushing this forward, I’d really like to know what your thoughts are regarding this?

- Rod

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto: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

Hi, Chris. Sorry for not responding directly – I assumed because your model was very close to this revised proposal, you wouldn't be expecting a direct response. At this point, I think the only discrepancy between your version and mine is that you'd use a shared annotation 'fragile' (or whatever) rather than an enum-specific annotation 'exhaustive' (or whatever). There are a few reasons why I didn't go with that:

- Unlike the other possible "fragility attributes" described in the Library Evolution <http://jrose-apple.github.io/swift-library-evolution/&gt; plan, 'exhaustive' changes the behavior of the type in a way that's visible to clients. Stating that a struct has a fixed set of stored properties, or that a function's definition can be inlined into a caller, acts purely as an optimization; it doesn't change what client source code can or cannot do with a type.

- Because exhaustivity affects clients, it's something that is useful for libraries distributed as source* as well as those with binary-compatibility concerns. If such a library provides an exhaustive enum in its public API, adding a new case would be a source-breaking change and require a major version bump (if the library is using semantic versioning <http://semver.org/&gt;\). Therefore, just like open and non-open classes, it is beneficial to distinguish between the exhaustive and non-exhaustive situations even for libraries distributed as source. Such libraries should have no need for the other fragility attributes because we expect to be able to perform those optimizations by default.

I really wish 'open' made sense here, because that's the closest analogous situation, but it just doesn't. So we need a separate annotation (although as mentioned in the proposal I'm okay with reusing 'final').

It does help now that `public enum` works without any further annotation; that's due to your feedback as well as pushes within Apple.

Jordan

* I'm saying "libraries distributed as source", but really this applies to any libraries that get packaged with the end product, usually an app. The real condition here is whether a client must be rebuilt to use a new version of the library, i.e. "libraries without binary compatibility concerns". These aren't officially supported by Apple today, but the model shouldn't leave them out.

···

On Sep 14, 2017, at 20:59, Chris Lattner <clattner@nondot.org> wrote:

On Sep 13, 2017, at 12:17 PM, Jordan Rose via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Proposal updated, same URL: https://github.com/jrose-apple/swift-evolution/blob/non-exhaustive-enums/proposals/nnnn-non-exhaustive-enums.md\.

Thanks again for all the feedback so far, everyone!

Hi Jordan,

I’d appreciate it if you could look at the comments I made upthread and respond to them. Thanks.

I am still unsure why we are choosing again a default that protects library writers more than library users where it is reasonable to expect the former to have better mastery of the language, to architect a library with some scalability, and ability to add unit test to cover themselves from issues than the latter.

Exhaustive and open by default with keywords to close things down if the framework author wants them.

···

Sent from my iPhone

On 16 Sep 2017, at 09:55, David Hart via swift-evolution <swift-evolution@swift.org> wrote:

I’m still very much bothered by having 2 new keywords. I would really prefer the following plan:

Exhaustive by default in Swift 4
No new keyword in Swift 4 to change that behaviour
Non-exhaustive by default outside the module in Swift 5
exhaustive keyword to change the default behaviour

Like that, we don’t need nonexhaustive.

Thoughts?
David.

On 13 Sep 2017, at 21:16, Jordan Rose via swift-evolution <swift-evolution@swift.org> wrote:

Proposal updated, same URL: https://github.com/jrose-apple/swift-evolution/blob/non-exhaustive-enums/proposals/nnnn-non-exhaustive-enums.md\.

Thanks again for all the feedback so far, everyone!
Jordan

On Sep 12, 2017, at 17:55, Jordan Rose via swift-evolution <swift-evolution@swift.org> wrote:

Sorry, I got distracted by other tasks! Both the discussion here and within Apple has moved towards making "non-exhaustive" the default, which, to be honest, I too think is the best design. I'll update the proposal today to reflect that, though I still want to keep both the "nonexhaustive" and "exhaustive" keywords for Swift 4 compatibility for now (or whatever we end up naming them). The compatibility design is a little less ambitious than Brent's; as currently proposed, Swift 4 mode continues to default to 'exhaustive' all the time, even in the actual Swift 5 release.

I still want to respond to Brent's points directly, but I think you and Vladimir have done a good job discussing them already. I'll send out the updated proposal tomorrow, after I have a little more time to think about #invalid.

Thanks for putting time into this!
Jordan

On Sep 9, 2017, at 17:34, Rod Brown <rodney.brown6@icloud.com> wrote:

Jordan,

Do you have any other thoughts about the ongoing discussion here, especially regarding Chris’ comments? As you’re the one pushing this forward, I’d really like to know what your thoughts are regarding this?

- Rod

_______________________________________________
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

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

Oops, forgot something:

"Can there be a kind of open enum where you can add new cases in extensions?”

I have a use case for this. I’m trying to write a database ORM with abstract API and concrete instances for different database. So I have defined:

open class Database {
   init(connectionDictionary: [ConnectionDictionaryKey:String]) {
        self.connectionDictionary = connectionDictionary;
    }
}

Where I have ConnectionDictionaryKey defined as an enum, with values like .hostName, .databaseName, .userName, .password, .databaseName, etc…

But concrete databases may have other options that need to be added to the connection dictionary. It would be nice if they could just extend ConnectionDictionaryKey with new cases.

-Kenny

···

On Sep 16, 2017, at 3:35 PM, Kenny Leung via swift-evolution <swift-evolution@swift.org> wrote:

In general, I agree with everything in the proposal.

I’d like to propose these alternative extensions for clients:

1) As a client of an enum, I’d like to know in the future when a new value has been added to an enum, since I may have to do something about it. How about adding the “exhaustive” keyword to be used in the switch statement? Like

exhaustive switch excuse {
    case eatenByPet:
        // …
    case thoughtItWasDueNextWeek:
        // …
    default:
        // …
}

If exhaustive is used, there would be a warning if all cases aren’t covered *even though default exists*. This means that I as the client thought I had everything covered when I wrote this code.

As already mentioned, this makes the default case un-testable, which brings me to

2) All non-exhaustive enums should have the pseudo value “default” that can be used just like a regular value. This would allow you to write code like:

teacher.failedToHandInHomework(excuse: .default)

which would allow you to trip the default case in any code you may write.

-Kenny

On Sep 13, 2017, at 12:17 PM, Jordan Rose via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Proposal updated, same URL: https://github.com/jrose-apple/swift-evolution/blob/non-exhaustive-enums/proposals/nnnn-non-exhaustive-enums.md\.

Thanks again for all the feedback so far, everyone!
Jordan

On Sep 12, 2017, at 17:55, Jordan Rose via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Sorry, I got distracted by other tasks! Both the discussion here and within Apple has moved towards making "non-exhaustive" the default, which, to be honest, I too think is the best design. I'll update the proposal today to reflect that, though I still want to keep both the "nonexhaustive" and "exhaustive" keywords for Swift 4 compatibility for now (or whatever we end up naming them). The compatibility design is a little less ambitious than Brent's; as currently proposed, Swift 4 mode continues to default to 'exhaustive' all the time, even in the actual Swift 5 release.

I still want to respond to Brent's points directly, but I think you and Vladimir have done a good job discussing them already. I'll send out the updated proposal tomorrow, after I have a little more time to think about #invalid.

Thanks for putting time into this!
Jordan

On Sep 9, 2017, at 17:34, Rod Brown <rodney.brown6@icloud.com <mailto:rodney.brown6@icloud.com>> wrote:

Jordan,

Do you have any other thoughts about the ongoing discussion here, especially regarding Chris’ comments? As you’re the one pushing this forward, I’d really like to know what your thoughts are regarding this?

- Rod

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

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto: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

I am still unsure why we are choosing again a default that protects library writers more than library users where it is reasonable to expect the former to have better mastery of the language, to architect a library with some scalability, and ability to add unit test to cover themselves from issues than the latter.

Because protecting library owners protects library users.

If you declare it is exhaustive and it was an oversight, and then realise after the fact that you are wrong, you have to open it up. This will break third party apps. It will be disallowed by the ABI compatibility requirements.

If you declare it isn’t exhaustive due to an oversight (or perhaps you’re just not sure yet), and then realise after the fact it is exhaustive, you can close it up. This will not break third party apps. It will also be allowed for ABI compatibility.

This benefits everyone. Make library owners choose a guarantee, rather than be defaulted into it. Much like they have to declare choose to declare “final” on a class: you can’t retroactively reneg that promise: it will break everyone who assumed it to be the case!

···

On 16 Sep 2017, at 7:22 pm, Goffredo Marocchi via swift-evolution <swift-evolution@swift.org> wrote:

Exhaustive and open by default with keywords to close things down if the framework author wants them.

Sent from my iPhone

On 16 Sep 2017, at 09:55, David Hart via swift-evolution <swift-evolution@swift.org> wrote:

I’m still very much bothered by having 2 new keywords. I would really prefer the following plan:

Exhaustive by default in Swift 4
No new keyword in Swift 4 to change that behaviour
Non-exhaustive by default outside the module in Swift 5
exhaustive keyword to change the default behaviour

Like that, we don’t need nonexhaustive.

Thoughts?
David.

On 13 Sep 2017, at 21:16, Jordan Rose via swift-evolution <swift-evolution@swift.org> wrote:

Proposal updated, same URL: https://github.com/jrose-apple/swift-evolution/blob/non-exhaustive-enums/proposals/nnnn-non-exhaustive-enums.md\.

Thanks again for all the feedback so far, everyone!
Jordan

On Sep 12, 2017, at 17:55, Jordan Rose via swift-evolution <swift-evolution@swift.org> wrote:

Sorry, I got distracted by other tasks! Both the discussion here and within Apple has moved towards making "non-exhaustive" the default, which, to be honest, I too think is the best design. I'll update the proposal today to reflect that, though I still want to keep both the "nonexhaustive" and "exhaustive" keywords for Swift 4 compatibility for now (or whatever we end up naming them). The compatibility design is a little less ambitious than Brent's; as currently proposed, Swift 4 mode continues to default to 'exhaustive' all the time, even in the actual Swift 5 release.

I still want to respond to Brent's points directly, but I think you and Vladimir have done a good job discussing them already. I'll send out the updated proposal tomorrow, after I have a little more time to think about #invalid.

Thanks for putting time into this!
Jordan

On Sep 9, 2017, at 17:34, Rod Brown <rodney.brown6@icloud.com> wrote:

Jordan,

Do you have any other thoughts about the ongoing discussion here, especially regarding Chris’ comments? As you’re the one pushing this forward, I’d really like to know what your thoughts are regarding this?

- Rod

_______________________________________________
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

_______________________________________________
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

That's pretty much the same as this proposal except you don't have the new keyword. I'm not sure why that really makes a difference, since they're obviously paired, and it would limit existing libraries from declaring exhaustive enums until they've moved entirely to Swift 5 mode. I think the current proposal makes sense as is.

Jordan

···

On Sep 16, 2017, at 01:55, David Hart <david@hartbit.com> wrote:

I’m still very much bothered by having 2 new keywords. I would really prefer the following plan:

Exhaustive by default in Swift 4
No new keyword in Swift 4 to change that behaviour
Non-exhaustive by default outside the module in Swift 5
exhaustive keyword to change the default behaviour

Like that, we don’t need nonexhaustive.

Thoughts?
David.

On 13 Sep 2017, at 21:16, Jordan Rose via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Proposal updated, same URL: https://github.com/jrose-apple/swift-evolution/blob/non-exhaustive-enums/proposals/nnnn-non-exhaustive-enums.md\.

Thanks again for all the feedback so far, everyone!
Jordan

On Sep 12, 2017, at 17:55, Jordan Rose via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Sorry, I got distracted by other tasks! Both the discussion here and within Apple has moved towards making "non-exhaustive" the default, which, to be honest, I too think is the best design. I'll update the proposal today to reflect that, though I still want to keep both the "nonexhaustive" and "exhaustive" keywords for Swift 4 compatibility for now (or whatever we end up naming them). The compatibility design is a little less ambitious than Brent's; as currently proposed, Swift 4 mode continues to default to 'exhaustive' all the time, even in the actual Swift 5 release.

I still want to respond to Brent's points directly, but I think you and Vladimir have done a good job discussing them already. I'll send out the updated proposal tomorrow, after I have a little more time to think about #invalid.

Thanks for putting time into this!
Jordan

On Sep 9, 2017, at 17:34, Rod Brown <rodney.brown6@icloud.com <mailto:rodney.brown6@icloud.com>> wrote:

Jordan,

Do you have any other thoughts about the ongoing discussion here, especially regarding Chris’ comments? As you’re the one pushing this forward, I’d really like to know what your thoughts are regarding this?

- Rod

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

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

In general, I agree with everything in the proposal.

I’d like to propose these alternative extensions for clients:

1) As a client of an enum, I’d like to know in the future when a new value has been added to an enum, since I may have to do something about it. How about adding the “exhaustive” keyword to be used in the switch statement? Like

exhaustive switch excuse {
    case eatenByPet:
        // …
    case thoughtItWasDueNextWeek:
        // …
    default:
        // …
}

If exhaustive is used, there would be a warning if all cases aren’t covered *even though default exists*. This means that I as the client thought I had everything covered when I wrote this code.

As already mentioned, this makes the default case un-testable, which brings me to

2) All non-exhaustive enums should have the pseudo value “default” that can be used just like a regular value. This would allow you to write code like:

teacher.failedToHandInHomework(excuse: .default)

which would allow you to trip the default case in any code you may write.

Brent came up with this idea as well, but after thinking it through Joe Groff and I found that it doesn't really work in practice:

It’s going to be very common to have a future value and hand it right back to the framework without looking at it, for example:

override func process(_ transaction: @testable Transaction) {
  switch transaction {
  case .deposit(let amount):
    // …
  case .withdrawal(let amount):
    // …
  default:
    super.process(transaction) // hmm…
  }
}

So just making it to the ‘default’ case doesn’t guarantee that it’s testable in practice.

I'll add the actual code here to the "Testing invalid cases" section under "Alternatives considered", since that's a clearer example than the paragraph I wrote. (Oh, and the "exhaustive switch" is equivalent to the section on "'future' cases".)

Thanks for the feedback!
Jordan

···

On Sep 16, 2017, at 15:35, Kenny Leung via swift-evolution <swift-evolution@swift.org> wrote:

I am still unsure why we are choosing again a default that protects library writers more than library users where it is reasonable to expect the former to have better mastery of the language, to architect a library with some scalability, and ability to add unit test to cover themselves from issues than the latter.

Because protecting library owners protects library users.

If a library writer can’t remember to declare non-exhaustive enums as such, they probably will forget many more important aspects of creating a library. They probably should not be writing libraries. Arguments like this make sense on the surface, but creating libraries involves hundreds or thousands of decisions. I wish you luck in making that process idiot proof. A library linter could easily warn that exposed enums are exhaustive. The exhaustive keyword should be optional to make the decision obvious and suppress warnings. Complicating the user experience in a vain attempt to make “expert" coding safer is misguided.

If you declare it is exhaustive and it was an oversight, and then realise after the fact that you are wrong, you have to open it up. This will break third party apps. It will be disallowed by the ABI compatibility requirements.

If you declare it isn’t exhaustive due to an oversight (or perhaps you’re just not sure yet), and then realise after the fact it is exhaustive, you can close it up. This will not break third party apps. It will also be allowed for ABI compatibility.

This benefits everyone. Make library owners choose a guarantee, rather than be defaulted into it. Much like they have to declare choose to declare “final” on a class: you can’t retroactively reneg that promise: it will break everyone who assumed it to be the case!

It does not benefit the creation of 90+% of enums. It is one more arcane rule for the vast majority of developers.

···

On Sep 16, 2017, at 8:41 AM, Rod Brown via swift-evolution <swift-evolution@swift.org> wrote:
On 16 Sep 2017, at 7:22 pm, Goffredo Marocchi via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Exhaustive and open by default with keywords to close things down if the framework author wants them.

Sent from my iPhone

On 16 Sep 2017, at 09:55, David Hart via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I’m still very much bothered by having 2 new keywords. I would really prefer the following plan:

Exhaustive by default in Swift 4
No new keyword in Swift 4 to change that behaviour
Non-exhaustive by default outside the module in Swift 5
exhaustive keyword to change the default behaviour

Like that, we don’t need nonexhaustive.

Thoughts?
David.

On 13 Sep 2017, at 21:16, Jordan Rose via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Proposal updated, same URL: https://github.com/jrose-apple/swift-evolution/blob/non-exhaustive-enums/proposals/nnnn-non-exhaustive-enums.md\.

Thanks again for all the feedback so far, everyone!
Jordan

On Sep 12, 2017, at 17:55, Jordan Rose via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Sorry, I got distracted by other tasks! Both the discussion here and within Apple has moved towards making "non-exhaustive" the default, which, to be honest, I too think is the best design. I'll update the proposal today to reflect that, though I still want to keep both the "nonexhaustive" and "exhaustive" keywords for Swift 4 compatibility for now (or whatever we end up naming them). The compatibility design is a little less ambitious than Brent's; as currently proposed, Swift 4 mode continues to default to 'exhaustive' all the time, even in the actual Swift 5 release.

I still want to respond to Brent's points directly, but I think you and Vladimir have done a good job discussing them already. I'll send out the updated proposal tomorrow, after I have a little more time to think about #invalid.

Thanks for putting time into this!
Jordan

On Sep 9, 2017, at 17:34, Rod Brown <rodney.brown6@icloud.com <mailto:rodney.brown6@icloud.com>> wrote:

Jordan,

Do you have any other thoughts about the ongoing discussion here, especially regarding Chris’ comments? As you’re the one pushing this forward, I’d really like to know what your thoughts are regarding this?

- Rod

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

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

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

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto: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

I am still unsure why we are choosing again a default that protects library writers more than library users where it is reasonable to expect the former to have better mastery of the language, to architect a library with some scalability, and ability to add unit test to cover themselves from issues than the latter.

Because protecting library owners protects library users.

If a library writer can’t remember to declare non-exhaustive enums as such, they probably will forget many more important aspects of creating a library. They probably should not be writing libraries. Arguments like this make sense on the surface, but creating libraries involves hundreds or thousands of decisions. I wish you luck in making that process idiot proof. A library linter could easily warn that exposed enums are exhaustive. The exhaustive keyword should be optional to make the decision obvious and suppress warnings. Complicating the user experience in a vain attempt to make “expert" coding safer is misguided.

This may be a little harsh, but there don’t seem to be many advocates for novice and “ordinary” application developers on this list. That is not unexpected given the number of extremely knowledgeable compiler and library developers on this list (for whom I have the highest respect). I believe that there are more creative (and probably more difficult to build) possible solutions to some of the tough problems in Swift’s future. In that spirit, see below.

If you declare it is exhaustive and it was an oversight, and then realise after the fact that you are wrong, you have to open it up. This will break third party apps. It will be disallowed by the ABI compatibility requirements.

If you declare it isn’t exhaustive due to an oversight (or perhaps you’re just not sure yet), and then realise after the fact it is exhaustive, you can close it up. This will not break third party apps. It will also be allowed for ABI compatibility.

This benefits everyone. Make library owners choose a guarantee, rather than be defaulted into it. Much like they have to declare choose to declare “final” on a class: you can’t retroactively reneg that promise: it will break everyone who assumed it to be the case!

It does not benefit the creation of 90+% of enums. It is one more arcane rule for the vast majority of developers.

The Swift compiler could offer a “strict enum exhaustiveness” (bikeshedding not included) switch that could be enabled by default for library targets and disabled by default for “application” targets. The switch would make not explicitly specifying exhaustiveness an error or warning when enabled. Perhaps this could be combined with other options that would tailor the development experience for library/application developers. This would help avoid “zero-sum” choices between benefitting library or application developers in the future.

Xcode and the SPM should be able to distinguish between the target types and generate the proper defaults. I do not believe that this is too mysterious for developers. There would be learning step for developers wiring their first library, but that is not necessarily a bad thing since creating a reusable library requires a different mindset than creating an application.

···

On Sep 16, 2017, at 11:28 AM, Christopher Kornher via swift-evolution <swift-evolution@swift.org> wrote:

On Sep 16, 2017, at 8:41 AM, Rod Brown via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
On 16 Sep 2017, at 7:22 pm, Goffredo Marocchi via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Exhaustive and open by default with keywords to close things down if the framework author wants them.

Sent from my iPhone

On 16 Sep 2017, at 09:55, David Hart via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I’m still very much bothered by having 2 new keywords. I would really prefer the following plan:

Exhaustive by default in Swift 4
No new keyword in Swift 4 to change that behaviour
Non-exhaustive by default outside the module in Swift 5
exhaustive keyword to change the default behaviour

Like that, we don’t need nonexhaustive.

Thoughts?
David.

On 13 Sep 2017, at 21:16, Jordan Rose via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Proposal updated, same URL: https://github.com/jrose-apple/swift-evolution/blob/non-exhaustive-enums/proposals/nnnn-non-exhaustive-enums.md\.

Thanks again for all the feedback so far, everyone!
Jordan

On Sep 12, 2017, at 17:55, Jordan Rose via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Sorry, I got distracted by other tasks! Both the discussion here and within Apple has moved towards making "non-exhaustive" the default, which, to be honest, I too think is the best design. I'll update the proposal today to reflect that, though I still want to keep both the "nonexhaustive" and "exhaustive" keywords for Swift 4 compatibility for now (or whatever we end up naming them). The compatibility design is a little less ambitious than Brent's; as currently proposed, Swift 4 mode continues to default to 'exhaustive' all the time, even in the actual Swift 5 release.

I still want to respond to Brent's points directly, but I think you and Vladimir have done a good job discussing them already. I'll send out the updated proposal tomorrow, after I have a little more time to think about #invalid.

Thanks for putting time into this!
Jordan

On Sep 9, 2017, at 17:34, Rod Brown <rodney.brown6@icloud.com <mailto:rodney.brown6@icloud.com>> wrote:

Jordan,

Do you have any other thoughts about the ongoing discussion here, especially regarding Chris’ comments? As you’re the one pushing this forward, I’d really like to know what your thoughts are regarding this?

- Rod

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

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

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

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

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

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

I run into use cases like this all the time…

I think I would prefer to see those concrete cases in a subtype though:

  enum DrinkSize {
    case small
    case medium
    case large
  }

  enum SummerDrinkSize : DrinkSize {
    //Inherits DrinkSize’s cases
    case extraLarge
  }

Because it is a subtype, you could place a SummerDrinkSize anywhere you can put a DrinkSize. As a result, all switches on it would need a default case to handle cases they hadn’t planned for. If you mark an enum with “final” then it can’t be extended and switches can be exhaustive.

In addition to inheriting the cases, a subtype would also inherit, and be able to override, methods defined on the super-type. You could use super to call the super-type’s implementation.

It is a bigger overhaul, but I think it actually ends up being semantically simpler for the end user. Basically, you can do the same types of things you can with classes... with the same syntax (just without the reference-type-ness).

It just so happens that this would also solve the problem of adding cases to (non-final) library enums, because switches of the enums would need to handle default/unexpected cases. That is a very abstract/confusing problem for end users who don’t write libraries to understand though. I think it is much easier to explain “final” as being the same as it is in classes, in that it prevents subclassing… which means you know what all the cases are.

More work (also more powerful), but semantically simpler. It just combines concepts we already know...

Thanks,
Jon

···

On Sep 16, 2017, at 3:51 PM, Kenny Leung via swift-evolution <swift-evolution@swift.org> wrote:

Oops, forgot something:

"Can there be a kind of open enum where you can add new cases in extensions?”

I have a use case for this. I’m trying to write a database ORM with abstract API and concrete instances for different database. So I have defined:

open class Database {
   init(connectionDictionary: [ConnectionDictionaryKey:String]) {
        self.connectionDictionary = connectionDictionary;
    }
}

Where I have ConnectionDictionaryKey defined as an enum, with values like .hostName, .databaseName, .userName, .password, .databaseName, etc…

But concrete databases may have other options that need to be added to the connection dictionary. It would be nice if they could just extend ConnectionDictionaryKey with new cases.

-Kenny

On Sep 16, 2017, at 3:35 PM, Kenny Leung via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

In general, I agree with everything in the proposal.

I’d like to propose these alternative extensions for clients:

1) As a client of an enum, I’d like to know in the future when a new value has been added to an enum, since I may have to do something about it. How about adding the “exhaustive” keyword to be used in the switch statement? Like

exhaustive switch excuse {
    case eatenByPet:
        // …
    case thoughtItWasDueNextWeek:
        // …
    default:
        // …
}

If exhaustive is used, there would be a warning if all cases aren’t covered *even though default exists*. This means that I as the client thought I had everything covered when I wrote this code.

As already mentioned, this makes the default case un-testable, which brings me to

2) All non-exhaustive enums should have the pseudo value “default” that can be used just like a regular value. This would allow you to write code like:

teacher.failedToHandInHomework(excuse: .default)

which would allow you to trip the default case in any code you may write.

-Kenny

On Sep 13, 2017, at 12:17 PM, Jordan Rose via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Proposal updated, same URL: https://github.com/jrose-apple/swift-evolution/blob/non-exhaustive-enums/proposals/nnnn-non-exhaustive-enums.md\.

Thanks again for all the feedback so far, everyone!
Jordan

On Sep 12, 2017, at 17:55, Jordan Rose via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Sorry, I got distracted by other tasks! Both the discussion here and within Apple has moved towards making "non-exhaustive" the default, which, to be honest, I too think is the best design. I'll update the proposal today to reflect that, though I still want to keep both the "nonexhaustive" and "exhaustive" keywords for Swift 4 compatibility for now (or whatever we end up naming them). The compatibility design is a little less ambitious than Brent's; as currently proposed, Swift 4 mode continues to default to 'exhaustive' all the time, even in the actual Swift 5 release.

I still want to respond to Brent's points directly, but I think you and Vladimir have done a good job discussing them already. I'll send out the updated proposal tomorrow, after I have a little more time to think about #invalid.

Thanks for putting time into this!
Jordan

On Sep 9, 2017, at 17:34, Rod Brown <rodney.brown6@icloud.com <mailto:rodney.brown6@icloud.com>> wrote:

Jordan,

Do you have any other thoughts about the ongoing discussion here, especially regarding Chris’ comments? As you’re the one pushing this forward, I’d really like to know what your thoughts are regarding this?

- Rod

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

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

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto: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

+1

···

On Sep 16, 2017, at 11:35 AM, Christopher Kornher via swift-evolution <swift-evolution@swift.org> wrote:

This may be a little harsh, but there don’t seem to be many advocates for novice and “ordinary” application developers on this list. That is not unexpected given the number of extremely knowledgeable compiler and library developers on this list (for whom I have the highest respect). I believe that there are more creative (and probably more difficult to build) possible solutions to some of the tough problems in Swift’s future.

If a library writer can’t remember to declare non-exhaustive enums as such, they probably will forget many more important aspects of creating a library. They probably should not be writing libraries. Arguments like this make sense on the surface, but creating libraries involves hundreds or thousands of decisions. I wish you luck in making that process idiot proof. A library linter could easily warn that exposed enums are exhaustive. The exhaustive keyword should be optional to make the decision obvious and suppress warnings. Complicating the user experience in a vain attempt to make “expert" coding safer is misguided.

I think the same logic goes both ways: If a library author can’t remember to declare exhaustive enums as such, they will probably forget many more important aspects of creating a library.

The problem here is fundamental: Exhaustive is a guarantee. A guarantee should require action. Non-Exhaustive guarantees nothing. It makes you safer. That is all.

This may be a little harsh, but there don’t seem to be many advocates for novice and “ordinary” application developers on this list. That is not unexpected given the number of extremely knowledgeable compiler and library developers on this list (for whom I have the highest respect). I believe that there are more creative (and probably more difficult to build) possible solutions to some of the tough problems in Swift’s future. In that spirit, see below.

I personally am an “ordinary” application developer.

I think the issue here is that everyone is seeing Swift as *they* intend to use it. For App Devs, exhaustive switches are nice, which means they really are fighting tooth and nail to keep them. I understand that. But I’m also trying to keep my mind open for “what happens to an app I compiled in iOS 15 that I compiled for iOS 11?” And this gives me pause. I can’t ask Apple or any other library author to be completely knowledgable about every case in the future, and to audit every line of code and manually give non-exhaustive.

Why do people want “exhaustive” to be the default? Because we like things as they are. Because we like not having to consider edge cases. Because we want to imagine that will give framework developers the control to make our lives difficult because they’ll just be lazy and make our lives hard by not annotating. And this certainly is a concern. But I think a larger concern is breaking apps left, right and centre, or not being able to extend frameworks because an earlier developer on a project made an oversight.

Its in everyone’s best interest to think before we put handcuffs on, no matter how painful that is. Even if that means you make apps where you just write “default: fatalError(“I don’t handle unreachable defaults”)"

And lets be clear: Swift isn’t an app development language. It also isn’t a framework development language. It’s a multipurpose language designed to Take Over The World™. This means we need to think holistically about what is better for everyone. Not just ourselves.

If you declare it is exhaustive and it was an oversight, and then realise after the fact that you are wrong, you have to open it up. This will break third party apps. It will be disallowed by the ABI compatibility requirements.

If you declare it isn’t exhaustive due to an oversight (or perhaps you’re just not sure yet), and then realise after the fact it is exhaustive, you can close it up. This will not break third party apps. It will also be allowed for ABI compatibility.

This benefits everyone. Make library owners choose a guarantee, rather than be defaulted into it. Much like they have to declare choose to declare “final” on a class: you can’t retroactively reneg that promise: it will break everyone who assumed it to be the case!

It does not benefit the creation of 90+% of enums. It is one more arcane rule for the vast majority of developers.

The Swift compiler could offer a “strict enum exhaustiveness” (bikeshedding not included) switch that could be enabled by default for library targets and disabled by default for “application” targets. The switch would make not explicitly specifying exhaustiveness an error or warning when enabled. Perhaps this could be combined with other options that would tailor the development experience for library/application developers. This would help avoid “zero-sum” choices between benefitting library or application developers in the future.

The Swift team have fundamentally opposed such pushes for “compiler modes” for a long time. I don’t expect they will embrace them now, nor do I think they should just to avoid us devs having to write the occasional “default” clause. This is, to be clear, a relatively rare case.

···

On 17 Sep 2017, at 4:35 am, Christopher Kornher <ckornher@me.com> wrote:

On Sep 16, 2017, at 11:28 AM, Christopher Kornher via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Xcode and the SPM should be able to distinguish between the target types and generate the proper defaults. I do not believe that this is too mysterious for developers. There would be learning step for developers wiring their first library, but that is not necessarily a bad thing since creating a reusable library requires a different mindset than creating an application.

Exhaustive and open by default with keywords to close things down if the framework author wants them.

Sent from my iPhone

On 16 Sep 2017, at 09:55, David Hart via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I’m still very much bothered by having 2 new keywords. I would really prefer the following plan:

Exhaustive by default in Swift 4
No new keyword in Swift 4 to change that behaviour
Non-exhaustive by default outside the module in Swift 5
exhaustive keyword to change the default behaviour

Like that, we don’t need nonexhaustive.

Thoughts?
David.

On 13 Sep 2017, at 21:16, Jordan Rose via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Proposal updated, same URL: https://github.com/jrose-apple/swift-evolution/blob/non-exhaustive-enums/proposals/nnnn-non-exhaustive-enums.md\.

Thanks again for all the feedback so far, everyone!
Jordan

On Sep 12, 2017, at 17:55, Jordan Rose via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Sorry, I got distracted by other tasks! Both the discussion here and within Apple has moved towards making "non-exhaustive" the default, which, to be honest, I too think is the best design. I'll update the proposal today to reflect that, though I still want to keep both the "nonexhaustive" and "exhaustive" keywords for Swift 4 compatibility for now (or whatever we end up naming them). The compatibility design is a little less ambitious than Brent's; as currently proposed, Swift 4 mode continues to default to 'exhaustive' all the time, even in the actual Swift 5 release.

I still want to respond to Brent's points directly, but I think you and Vladimir have done a good job discussing them already. I'll send out the updated proposal tomorrow, after I have a little more time to think about #invalid.

Thanks for putting time into this!
Jordan

On Sep 9, 2017, at 17:34, Rod Brown <rodney.brown6@icloud.com <mailto:rodney.brown6@icloud.com>> wrote:

Jordan,

Do you have any other thoughts about the ongoing discussion here, especially regarding Chris’ comments? As you’re the one pushing this forward, I’d really like to know what your thoughts are regarding this?

- Rod

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

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

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

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

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

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

I am still unsure why we are choosing again a default that protects library writers more than library users where it is reasonable to expect the former to have better mastery of the language, to architect a library with some scalability, and ability to add unit test to cover themselves from issues than the latter.

Because protecting library owners protects library users.

If a library writer can’t remember to declare non-exhaustive enums as such, they probably will forget many more important aspects of creating a library. They probably should not be writing libraries. Arguments like this make sense on the surface, but creating libraries involves hundreds or thousands of decisions. I wish you luck in making that process idiot proof. A library linter could easily warn that exposed enums are exhaustive. The exhaustive keyword should be optional to make the decision obvious and suppress warnings. Complicating the user experience in a vain attempt to make “expert" coding safer is misguided.

This may be a little harsh, but there don’t seem to be many advocates for novice and “ordinary” application developers on this list. That is not unexpected given the number of extremely knowledgeable compiler and library developers on this list (for whom I have the highest respect). I believe that there are more creative (and probably more difficult to build) possible solutions to some of the tough problems in Swift’s future. In that spirit, see below.

It's definitely good to consider the effects on normal application developers!

If you declare it is exhaustive and it was an oversight, and then realise after the fact that you are wrong, you have to open it up. This will break third party apps. It will be disallowed by the ABI compatibility requirements.

If you declare it isn’t exhaustive due to an oversight (or perhaps you’re just not sure yet), and then realise after the fact it is exhaustive, you can close it up. This will not break third party apps. It will also be allowed for ABI compatibility.

This benefits everyone. Make library owners choose a guarantee, rather than be defaulted into it. Much like they have to declare choose to declare “final” on a class: you can’t retroactively reneg that promise: it will break everyone who assumed it to be the case!

It does not benefit the creation of 90+% of enums. It is one more arcane rule for the vast majority of developers.

The Swift compiler could offer a “strict enum exhaustiveness” (bikeshedding not included) switch that could be enabled by default for library targets and disabled by default for “application” targets. The switch would make not explicitly specifying exhaustiveness an error or warning when enabled. Perhaps this could be combined with other options that would tailor the development experience for library/application developers. This would help avoid “zero-sum” choices between benefitting library or application developers in the future.

Xcode and the SPM should be able to distinguish between the target types and generate the proper defaults. I do not believe that this is too mysterious for developers. There would be learning step for developers wiring their first library, but that is not necessarily a bad thing since creating a reusable library requires a different mindset than creating an application.

Right now we have this notion, but the difference between library and app is signified by "public". My opinion is that between the choices of "multi-module applications have to deal with everything SwiftPM packages do" and "there are different rules for multi-module applications and for SwiftPM packages", the former is preferable just in terms of overall complexity in the language. It's certainly a trade-off! But that's what I'm proposing, and it should be very clear what to do when multi-module app developers encounter the additional rules that come with, well, having multiple modules.

(We're already likely to have an extra distinction between "libraries built with support for binary compatibility" and "libraries built to be distributed with their clients", but it's still better if that too avoids splitting the language into dialects.)

Jordan

···

On Sep 16, 2017, at 11:35, Christopher Kornher via swift-evolution <swift-evolution@swift.org> wrote:

On Sep 16, 2017, at 11:28 AM, Christopher Kornher via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Sep 16, 2017, at 8:41 AM, Rod Brown via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
On 16 Sep 2017, at 7:22 pm, Goffredo Marocchi via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

As mentioned, the right way to do this is with a struct:

public struct ConnectionDictionaryKey: RawRepresentable, Hashable {
  public var rawValue: String
  public init(rawValue: String) { … }
  public init(_ rawValue: String) { … }
}
extension ConnectionDictionaryKey {
  static let hostName = ConnectionDictionaryKey("hostname")
  static let databaseName = ConnectionDictionaryKey("database")
  // …
}

It is definitely more verbose than an enum, and it may be worth a separate proposal to deal with that! But it is not part of this proposal, and what you're describing isn't really an enum.

Jordan

···

On Sep 16, 2017, at 15:51, Kenny Leung via swift-evolution <swift-evolution@swift.org> wrote:

Oops, forgot something:

"Can there be a kind of open enum where you can add new cases in extensions?”

I have a use case for this. I’m trying to write a database ORM with abstract API and concrete instances for different database. So I have defined:

open class Database {
   init(connectionDictionary: [ConnectionDictionaryKey:String]) {
        self.connectionDictionary = connectionDictionary;
    }
}

Where I have ConnectionDictionaryKey defined as an enum, with values like .hostName, .databaseName, .userName, .password, .databaseName, etc…

But concrete databases may have other options that need to be added to the connection dictionary. It would be nice if they could just extend ConnectionDictionaryKey with new cases.

-Kenny

On Sep 16, 2017, at 3:35 PM, Kenny Leung via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

In general, I agree with everything in the proposal.

I’d like to propose these alternative extensions for clients:

1) As a client of an enum, I’d like to know in the future when a new value has been added to an enum, since I may have to do something about it. How about adding the “exhaustive” keyword to be used in the switch statement? Like

exhaustive switch excuse {
    case eatenByPet:
        // …
    case thoughtItWasDueNextWeek:
        // …
    default:
        // …
}

If exhaustive is used, there would be a warning if all cases aren’t covered *even though default exists*. This means that I as the client thought I had everything covered when I wrote this code.

As already mentioned, this makes the default case un-testable, which brings me to

2) All non-exhaustive enums should have the pseudo value “default” that can be used just like a regular value. This would allow you to write code like:

teacher.failedToHandInHomework(excuse: .default)

which would allow you to trip the default case in any code you may write.

-Kenny

On Sep 13, 2017, at 12:17 PM, Jordan Rose via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Proposal updated, same URL: https://github.com/jrose-apple/swift-evolution/blob/non-exhaustive-enums/proposals/nnnn-non-exhaustive-enums.md\.

Thanks again for all the feedback so far, everyone!
Jordan

On Sep 12, 2017, at 17:55, Jordan Rose via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Sorry, I got distracted by other tasks! Both the discussion here and within Apple has moved towards making "non-exhaustive" the default, which, to be honest, I too think is the best design. I'll update the proposal today to reflect that, though I still want to keep both the "nonexhaustive" and "exhaustive" keywords for Swift 4 compatibility for now (or whatever we end up naming them). The compatibility design is a little less ambitious than Brent's; as currently proposed, Swift 4 mode continues to default to 'exhaustive' all the time, even in the actual Swift 5 release.

I still want to respond to Brent's points directly, but I think you and Vladimir have done a good job discussing them already. I'll send out the updated proposal tomorrow, after I have a little more time to think about #invalid.

Thanks for putting time into this!
Jordan

On Sep 9, 2017, at 17:34, Rod Brown <rodney.brown6@icloud.com <mailto:rodney.brown6@icloud.com>> wrote:

Jordan,

Do you have any other thoughts about the ongoing discussion here, especially regarding Chris’ comments? As you’re the one pushing this forward, I’d really like to know what your thoughts are regarding this?

- Rod

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

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

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto: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