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

2018-01-05 Thread Jordan Rose via swift-evolution
Clarifications here only! I don't think I have too much more to convince you; 
at this point we've looked at the same landscape and come to different 
conclusions. Although I think I'm more optimistic than you are about being able 
to build a binary compatibility checker.


> On Jan 5, 2018, at 06:52, Swift  wrote:
> 
>> They can't tell themselves whether your app supports the new case, other 
>> than the heavy-handed "check what SDK they compiled against" that ignores 
>> the possibility of embedded binary frameworks. 
> 
> To be fair, a “linked on or after” check isn’t that heavy-handed. It’s a 
> single if-statement. Yes, they become unwieldy if you’ve got them 
> *everywhere* in your library code, which is why I brought up the point 
> earlier that I’d really love to see more in the way of facilitating this sort 
> of link-dependent behavior that apps are expecting.

Just to clear up this point, I meant "heavy-handed" in that it's just an 
approximation of whether the client is actually ready to deal with new 
complexity. It's not an unreasonable one, but it still forces clients to 
potentially think about all the new things if they just want to update to use 
one of them.

Maybe "coarse-grained" would have been better phrasing. That also covers the 
"on or off for the entire app" aspect.


>>> Teaching the compiler/checker/whatever about the linking semantics of 
>>> modules. For modules that are packaged inside the final built product, 
>>> there is no need to deal with any unexpected cases, because we already have 
>>> the exhaustiveness check appropriate for that scenario (regardless of 
>>> whether the module is shipped as a binary or compiled from source). The app 
>>> author decides when to update their dependencies, and updating those 
>>> dependencies will produce new warnings/errors as the compiler notices new 
>>> or deprecated cases. This is the current state of things and is completely 
>>> orthogonal to the entire discussion.
>> 
>> This keeps sneaking into discussions and I hope to have it formalized in a 
>> proposal soon. On the library side, we do want to make a distinction between 
>> "needs binary compatibility" and "does not need binary compatibility". Why? 
>> Because we can get much better performance if we know a library is never 
>> going to change. A class will not acquire new dynamic-dispatch members; a 
>> stored property will not turn into a computed property; a struct will not 
>> gain new stored properties. None of those things affect how client code is 
>> written, but they do affect what happens at run-time.
> 
> This is incorrect; binary compatibility absolutely affects how code is 
> written. No swift library available today is written with binary 
> compatibility in mind, because it’s a non-issue. If it were a pervasive 
> issue, then you’d see a lot more diligence in libraries about not straight-up 
> breaking things between releases.
> 
> Other responses on this thread have mentioned removing implementations 
> between releases, which is an excellent illustration of this point: when 
> writing a binary-compatible library, *you cannot remove implementations*. So 
> the very fact that people think that it’s ok to do so is an explicit 
> refutation of the assertion that the manner in which client code is written 
> is independent of the consideration of a library needing binary compatibility.

I very carefully said "client", and then Ted reminded me yesterday in another 
context that that's not a standard term. So to be clear, I meant "none of these 
performance-related things would change what an app can and can't do with the 
API of the library", not anything broader about the design of the library or 
even about the design of the app.

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


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

2018-01-05 Thread Karl Wagner via swift-evolution

> On 5. Jan 2018, at 15:52, Swift via swift-evolution 
>  wrote:
> 
> Hi Jordan,
> 
> Thanks for your thoughtful reply. Comments inline...
> 
> Sent from my iPad
> 
> On Jan 4, 2018, at 5:37 PM, Jordan Rose  > wrote:
> 
>> Hi, Dave. You're right, all these points are worth addressing. I'm going to 
>> go in sections.
>> 
>>> This whole “unexpected case” thing is only a problem when you’re linking 
>>> libraries that are external to/shipped independently of your app. Right 
>>> now, the *only* case where this might exist is Swift on the server. We 
>>> *might* run in to this in the future once the ABI stabilizes and we have 
>>> the Swift libraries shipping as part of iOS/macOS/Linux. Other than this, 
>>> unexpected enum cases won’t really be a problem developers have to deal 
>>> with.
>> 
>> 
>> I wish this were the case, but it is not. Regardless of what we do for Swift 
>> enums, we are in dire need of a fix for C enums. Today, if a C enum doesn't 
>> have one of the expected values, the behavior is undefined in the C sense 
>> (as in, type-unsafe, memory-unsafe, may invoke functions that shouldn't be 
>> invoked, may not invoke functions that should be invoked, etc).
> 
> That’s a fair point, and one I had forgotten about. Thanks for reminding me.
> 
>> Obviously that's an unacceptable state of affairs; even without this 
>> proposal we would fix it so that the program will deterministically trap 
>> instead. This isn't perfect because it results in a (tiny) performance and 
>> code size hit compared to C, but it's better than leaving such a massive 
>> hole in Swift's safety story.
>> 
>> The trouble is that many enums—maybe even most enums—in the Apple SDK really 
>> are expected to grow new cases, and the Apple API authors rely on this. Many 
>> of those—probably most of them—are the ones that Brent Royal-Gordon 
>> described as "opaque inputs", like UIViewAnimationTransition, which you're 
>> unlikely to switch over but which the compiler should handle correctly if 
>> you do. Then there are the murkier ones like SKPaymentTransactionState.
>> 
>> I'm going to come dangerously close to criticizing Apple and say I have a 
>> lot of sympathy for third-party developers in the SKPaymentTransactionState 
>> case. 
> 
> This isn’t criticism.
> 
> 
> You’re acknowledging the complexities that exist when writing software, from 
> the point-of-view of someone who has no insight in to the intricacies and 
> challenges faced by the StoreKit team. Our takeaway from this is that no one 
> writes perfect code.
> 
> 
> 
> 
>> As Karl Wagner said, there wasn't really any way an existing app could 
>> handle that case well, even if they had written an 'unknown case' handler. 
>> So what could the StoreKit folks have done instead? 
> 
> Well, the converse is also true: what reasonable logic exists that an app 
> developer could do to handle a new transaction state for which they’re 
> unprepared? The only sensical thing would be to abort the transaction, 
> apologize to the user, and quickly release an update to your app.
> 
>> They can't tell themselves whether your app supports the new case, other 
>> than the heavy-handed "check what SDK they compiled against" that ignores 
>> the possibility of embedded binary frameworks. 
> 
> To be fair, a “linked on or after” check isn’t that heavy-handed. It’s a 
> single if-statement. Yes, they become unwieldy if you’ve got them 
> *everywhere* in your library code, which is why I brought up the point 
> earlier that I’d really love to see more in the way of facilitating this sort 
> of link-dependent behavior that apps are expecting.
> 
> The software-level solution is to make everything require a configuration 
> object (as you allude to below), but a lower-level solution would (hopefully) 
> be even nicer.
> 
>> So maybe they should have added a property "supportsDeferredState" or 
>> something that would have to be set before the new state was returned.
>> 
>> (I'll pause to say I don't know what consideration went into this API and 
>> I'm going to avoid looking it up to avoid perjury. This is all hypothetical, 
>> for the next API that needs to add a case.)
>> 
>> Let's say we go with that, a property that controls whether the new case is 
>> ever passed to third-party code. Now the new case exists, and new code needs 
>> to switch over it. At the same time, old code needs to continue working. The 
>> new enum case exists, and so even if it shouldn't escape into old code that 
>> doesn't know how to handle it, the behavior needs to be defined if it does. 
>> Furthermore, the old code needs to continue working without source changes, 
>> because updating to a new SDK must not break existing code. (It can 
>> introduce new warnings, but even that is something that should be considered 
>> carefully.)
>> 
>> So: this proposal is designed to handle the use cases both for Swift library 
>> 

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

2018-01-05 Thread Swift via swift-evolution
Hi Jordan,

Thanks for your thoughtful reply. Comments inline...

Sent from my iPad

> On Jan 4, 2018, at 5:37 PM, Jordan Rose  wrote:
> 
> Hi, Dave. You're right, all these points are worth addressing. I'm going to 
> go in sections.
> 
>> This whole “unexpected case” thing is only a problem when you’re linking 
>> libraries that are external to/shipped independently of your app. Right now, 
>> the *only* case where this might exist is Swift on the server. We *might* 
>> run in to this in the future once the ABI stabilizes and we have the Swift 
>> libraries shipping as part of iOS/macOS/Linux. Other than this, unexpected 
>> enum cases won’t really be a problem developers have to deal with.
> 
> 
> I wish this were the case, but it is not. Regardless of what we do for Swift 
> enums, we are in dire need of a fix for C enums. Today, if a C enum doesn't 
> have one of the expected values, the behavior is undefined in the C sense (as 
> in, type-unsafe, memory-unsafe, may invoke functions that shouldn't be 
> invoked, may not invoke functions that should be invoked, etc).

That’s a fair point, and one I had forgotten about. Thanks for reminding me.

> Obviously that's an unacceptable state of affairs; even without this proposal 
> we would fix it so that the program will deterministically trap instead. This 
> isn't perfect because it results in a (tiny) performance and code size hit 
> compared to C, but it's better than leaving such a massive hole in Swift's 
> safety story.
> 
> The trouble is that many enums—maybe even most enums—in the Apple SDK really 
> are expected to grow new cases, and the Apple API authors rely on this. Many 
> of those—probably most of them—are the ones that Brent Royal-Gordon described 
> as "opaque inputs", like UIViewAnimationTransition, which you're unlikely to 
> switch over but which the compiler should handle correctly if you do. Then 
> there are the murkier ones like SKPaymentTransactionState.
> 
> I'm going to come dangerously close to criticizing Apple and say I have a lot 
> of sympathy for third-party developers in the SKPaymentTransactionState case.

This isn’t criticism.


You’re acknowledging the complexities that exist when writing software, from 
the point-of-view of someone who has no insight in to the intricacies and 
challenges faced by the StoreKit team. Our takeaway from this is that no one 
writes perfect code.




> As Karl Wagner said, there wasn't really any way an existing app could handle 
> that case well, even if they had written an 'unknown case' handler. So what 
> could the StoreKit folks have done instead?

Well, the converse is also true: what reasonable logic exists that an app 
developer could do to handle a new transaction state for which they’re 
unprepared? The only sensical thing would be to abort the transaction, 
apologize to the user, and quickly release an update to your app.

> They can't tell themselves whether your app supports the new case, other than 
> the heavy-handed "check what SDK they compiled against" that ignores the 
> possibility of embedded binary frameworks.

To be fair, a “linked on or after” check isn’t that heavy-handed. It’s a single 
if-statement. Yes, they become unwieldy if you’ve got them *everywhere* in your 
library code, which is why I brought up the point earlier that I’d really love 
to see more in the way of facilitating this sort of link-dependent behavior 
that apps are expecting.

The software-level solution is to make everything require a configuration 
object (as you allude to below), but a lower-level solution would (hopefully) 
be even nicer.

> So maybe they should have added a property "supportsDeferredState" or 
> something that would have to be set before the new state was returned.
> 
> (I'll pause to say I don't know what consideration went into this API and I'm 
> going to avoid looking it up to avoid perjury. This is all hypothetical, for 
> the next API that needs to add a case.)
> 
> Let's say we go with that, a property that controls whether the new case is 
> ever passed to third-party code. Now the new case exists, and new code needs 
> to switch over it. At the same time, old code needs to continue working. The 
> new enum case exists, and so even if it shouldn't escape into old code that 
> doesn't know how to handle it, the behavior needs to be defined if it does. 
> Furthermore, the old code needs to continue working without source changes, 
> because updating to a new SDK must not break existing code. (It can introduce 
> new warnings, but even that is something that should be considered carefully.)
> 
> So: this proposal is designed to handle the use cases both for Swift library 
> authors to come and for C APIs today, and in particular Apple's Objective-C 
> SDKs and how they've evolved historically.
> 
> 
> There's another really interesting point in your message, which Karl, Drew 
> Crawford, and others also touched on.
> 
>> Teaching the 

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

2018-01-05 Thread Gwendal Roué via swift-evolution

> Le 5 janv. 2018 à 10:33, Goffredo Marocchi  a écrit :
> 
> Fair concerns Gwendal, but why can’t the default in these cases be just 
> exhaustive / frozen unless the library developer explicitly marks it as 
> “unfrozen/non exhaustive” and the compiler can warn the users when they 
> switch over it instead of throwing an error by default (the user can still 
> treat warnings as errors if they want and suppress this warning if they 
> wanted to in this vision)?

The proposal suggests default non-frozen enums. If I remember well, that's 
because it's easier to switch from non-frozen to frozen than the opposite.

I buy this ABI-based argument very well, since 1. I'm not an ABI expert, and 2. 
as a library author I will scratch my head for each of my public enums anyway.

Now I still think that the choice is really uneasy. I've given some GRDB 
examples. And I'd also like to know how ABI experts would have introduced and 
evolved SKPaymentTransactionState in a hypothetic Swift 5+ world.

Gwendal

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


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

2018-01-05 Thread Goffredo Marocchi via swift-evolution
Fair concerns Gwendal, but why can’t the default in these cases be just 
exhaustive / frozen unless the library developer explicitly marks it as 
“unfrozen/non exhaustive” and the compiler can warn the users when they switch 
over it instead of throwing an error by default (the user can still treat 
warnings as errors if they want and suppress this warning if they wanted to in 
this vision)?

I think, sorry if I am being presumptions, that the onus in this case should be 
on the library author to mark enums and opt in in this non exhaustive 
behaviour. @Jordan what would the issue in this be?

Sent from my iPhone

> On 5 Jan 2018, at 09:11, Gwendal Roué  wrote:
> 
> 
>> Le 5 janv. 2018 à 09:11, Goffredo Marocchi via swift-evolution 
>>  a écrit :
>> 
>> I feel like this change will make the life easier for library authors, but 
>> risks making it easier and easier to make mistakes in apps using the 
>> libraries: exhaustive switching over enums is a good important feature that 
>> risks going away (the default matters) for not a huge effective benefit to 
>> app developers.
> 
> I agree that life is made worse for a library user that meets a non-frozen 
> enum. And I don't know if it makes the life easier for library authors, 
> because library authors not only throw code in the wild, but also try to 
> prevent library users from making the mistakes you talk about.
> 
> To take GRDB.swift as an example, it currently has 15 public enums. What are 
> my options?
> 
> More than half of those enums mirror SQLite C enums, or sets of related 
> SQLite values. SQLite is still a living piece of sofware, and it may adds new 
> cases or values in the future. It is then likely that GRDB has to be updated 
> as well. It thus looks like I can make those enums @frozen. But then it looks 
> like I betray the proposal's goal. What's the correct choice?
> 
> Some enums are like SKPaymentTransactionState: there's no way the user could 
> infer a proper behavior in a mandatory default/unknown switch case. I thus 
> also want to make them @frozen, and avoid headaches to the library users. 
> Will I pay for it later?
> 
> Some other enums are positively non-frozen. I may want to replace some of 
> them with a struct with a limited set of pre-built values. This would, IMHO, 
> improve the library UX because it would again prevent headaches for the 
> library users about scary "future" cases. In the struct with a limited set of 
> values, there is no future cases. Instead, there are a limited set of named 
> values. Which is a very different way to say the same thing.
> 
> This last paragraph draws a strong parallel between non-frozen enums and 
> structs:
> 
> // non-frozen enum:
> public enum E {
> case a, b
> }
> 
> // equivalent struct:
> public struct S: Equatable {
> private let value: Int
> private init(_ value: Int) { self.value = value }
> public static let a = S(1)
> public static let b = S(2)
> public static func == (lhs: S, rhs: S) -> Bool {
> return lhs.value == rhs.value
> }
> }
> 
> func f(_ s: S) {
> // S can be switched over just like a struct:
> switch s {
> case .a: print("a")
> case .b: print("b")
> default: print("unknown")
> }
> }
> 
> BTW, did anybody think about importing C enums as such structs?
> 
> Gwendal
> 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2018-01-05 Thread Gwendal Roué via swift-evolution

> Le 5 janv. 2018 à 09:11, Goffredo Marocchi via swift-evolution 
>  a écrit :
> 
> I feel like this change will make the life easier for library authors, but 
> risks making it easier and easier to make mistakes in apps using the 
> libraries: exhaustive switching over enums is a good important feature that 
> risks going away (the default matters) for not a huge effective benefit to 
> app developers.

I agree that life is made worse for a library user that meets a non-frozen 
enum. And I don't know if it makes the life easier for library authors, because 
library authors not only throw code in the wild, but also try to prevent 
library users from making the mistakes you talk about.

To take GRDB.swift as an example, it currently has 15 public enums. What are my 
options?

More than half of those enums mirror SQLite C enums, or sets of related SQLite 
values. SQLite is still a living piece of sofware, and it may adds new cases or 
values in the future. It is then likely that GRDB has to be updated as well. It 
thus looks like I can make those enums @frozen. But then it looks like I betray 
the proposal's goal. What's the correct choice?

Some enums are like SKPaymentTransactionState: there's no way the user could 
infer a proper behavior in a mandatory default/unknown switch case. I thus also 
want to make them @frozen, and avoid headaches to the library users. Will I pay 
for it later?

Some other enums are positively non-frozen. I may want to replace some of them 
with a struct with a limited set of pre-built values. This would, IMHO, improve 
the library UX because it would again prevent headaches for the library users 
about scary "future" cases. In the struct with a limited set of values, there 
is no future cases. Instead, there are a limited set of named values. Which is 
a very different way to say the same thing.

This last paragraph draws a strong parallel between non-frozen enums and 
structs:

// non-frozen enum:
public enum E {
case a, b
}

// equivalent struct:
public struct S: Equatable {
private let value: Int
private init(_ value: Int) { self.value = value }
public static let a = S(1)
public static let b = S(2)
public static func == (lhs: S, rhs: S) -> Bool {
return lhs.value == rhs.value
}
}

func f(_ s: S) {
// S can be switched over just like a struct:
switch s {
case .a: print("a")
case .b: print("b")
default: print("unknown")
}
}

BTW, did anybody think about importing C enums as such structs?

Gwendal

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


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

2018-01-05 Thread Goffredo Marocchi via swift-evolution
Code that ends up running in a default case somewhere in one of the several 
places you switch over that enum that you forgot about... well, it may not 
break source code compatibility, but it may introduce subtle bugs... submarine 
bugs.

Sent from my iPhone

> On 5 Jan 2018, at 08:11, Goffredo Marocchi via swift-evolution 
>  wrote:
> 
> 
>> On 5 Jan 2018, at 00:38, Jordan Rose via swift-evolution 
>>  wrote:
>> 
>> Furthermore, the old code needs to continue working without source changes, 
>> because updating to a new SDK must not break existing code. (It can 
>> introduce new warnings, but even that is something that should be considered 
>> carefully.)
>> 
>> So: this proposal is designed to handle the use cases both for Swift library 
>> authors to come and for C APIs today, and in particular Apple's Objective-C 
>> SDKs and how they've evolved historically.
> 
> I will let your very comprehensive rationale brew a little bit more in my 
> mind and reread it, but I still think this is a bit leaning too much over to 
> library authors than library consumers (not unlike the closed by default 
> discussion we all had a while ago).
> 
> I remain very unconvinced by the “updating library/SDK” must be source 
> compatible. Especially if it is major version change and a deprecated method 
> has been removed, methods have changed signature, etc... Backward compatible 
> runtime with code compiled against the previous SDK yes, source compatible no.
> 
> I feel like this change will make the life easier for library authors, but 
> risks making it easier and easier to make mistakes in apps using the 
> libraries: exhaustive switching over enums is a good important feature that 
> risks going away (the default matters) for not a huge effective benefit to 
> app developers.
> ___
> 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


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

2018-01-05 Thread Goffredo Marocchi via swift-evolution

> On 5 Jan 2018, at 00:38, Jordan Rose via swift-evolution 
>  wrote:
> 
> Furthermore, the old code needs to continue working without source changes, 
> because updating to a new SDK must not break existing code. (It can introduce 
> new warnings, but even that is something that should be considered carefully.)
> 
> So: this proposal is designed to handle the use cases both for Swift library 
> authors to come and for C APIs today, and in particular Apple's Objective-C 
> SDKs and how they've evolved historically.

I will let your very comprehensive rationale brew a little bit more in my mind 
and reread it, but I still think this is a bit leaning too much over to library 
authors than library consumers (not unlike the closed by default discussion we 
all had a while ago).

I remain very unconvinced by the “updating library/SDK” must be source 
compatible. Especially if it is major version change and a deprecated method 
has been removed, methods have changed signature, etc... Backward compatible 
runtime with code compiled against the previous SDK yes, source compatible no.

I feel like this change will make the life easier for library authors, but 
risks making it easier and easier to make mistakes in apps using the libraries: 
exhaustive switching over enums is a good important feature that risks going 
away (the default matters) for not a huge effective benefit to app developers.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2018-01-04 Thread Gwendal Roué via swift-evolution
May I ask two questions?

Would StoreKit be written in Swift 5+, do you think that 
SKPaymentTransactionState should have been introduced as a @closed enum?

If so, what would have then been the consequences of adding the new .deferred 
state (assuming this would even be possible)?

Gwendal

> Le 5 janv. 2018 à 01:38, Jordan Rose via swift-evolution 
>  a écrit :
> 
> Hi, Dave. You're right, all these points are worth addressing. I'm going to 
> go in sections.
> 
>> This whole “unexpected case” thing is only a problem when you’re linking 
>> libraries that are external to/shipped independently of your app. Right now, 
>> the *only* case where this might exist is Swift on the server. We *might* 
>> run in to this in the future once the ABI stabilizes and we have the Swift 
>> libraries shipping as part of iOS/macOS/Linux. Other than this, unexpected 
>> enum cases won’t really be a problem developers have to deal with.
> 
> 
> I wish this were the case, but it is not. Regardless of what we do for Swift 
> enums, we are in dire need of a fix for C enums. Today, if a C enum doesn't 
> have one of the expected values, the behavior is undefined in the C sense (as 
> in, type-unsafe, memory-unsafe, may invoke functions that shouldn't be 
> invoked, may not invoke functions that should be invoked, etc).
> 
> Obviously that's an unacceptable state of affairs; even without this proposal 
> we would fix it so that the program will deterministically trap instead. This 
> isn't perfect because it results in a (tiny) performance and code size hit 
> compared to C, but it's better than leaving such a massive hole in Swift's 
> safety story.
> 
> The trouble is that many enums—maybe even most enums—in the Apple SDK really 
> are expected to grow new cases, and the Apple API authors rely on this. Many 
> of those—probably most of them—are the ones that Brent Royal-Gordon described 
> as "opaque inputs", like UIViewAnimationTransition, which you're unlikely to 
> switch over but which the compiler should handle correctly if you do. Then 
> there are the murkier ones like SKPaymentTransactionState.
> 
> I'm going to come dangerously close to criticizing Apple and say I have a lot 
> of sympathy for third-party developers in the SKPaymentTransactionState case. 
> As Karl Wagner said, there wasn't really any way an existing app could handle 
> that case well, even if they had written an 'unknown case' handler. So what 
> could the StoreKit folks have done instead? They can't tell themselves 
> whether your app supports the new case, other than the heavy-handed "check 
> what SDK they compiled against" that ignores the possibility of embedded 
> binary frameworks. So maybe they should have added a property 
> "supportsDeferredState" or something that would have to be set before the new 
> state was returned.
> 
> (I'll pause to say I don't know what consideration went into this API and I'm 
> going to avoid looking it up to avoid perjury. This is all hypothetical, for 
> the next API that needs to add a case.)
> 
> Let's say we go with that, a property that controls whether the new case is 
> ever passed to third-party code. Now the new case exists, and new code needs 
> to switch over it. At the same time, old code needs to continue working. The 
> new enum case exists, and so even if it shouldn't escape into old code that 
> doesn't know how to handle it, the behavior needs to be defined if it does. 
> Furthermore, the old code needs to continue working without source changes, 
> because updating to a new SDK must not break existing code. (It can introduce 
> new warnings, but even that is something that should be considered carefully.)
> 
> So: this proposal is designed to handle the use cases both for Swift library 
> authors to come and for C APIs today, and in particular Apple's Objective-C 
> SDKs and how they've evolved historically.
> 
> 
> There's another really interesting point in your message, which Karl, Drew 
> Crawford, and others also touched on.
> 
>> Teaching the compiler/checker/whatever about the linking semantics of 
>> modules. For modules that are packaged inside the final built product, there 
>> is no need to deal with any unexpected cases, because we already have the 
>> exhaustiveness check appropriate for that scenario (regardless of whether 
>> the module is shipped as a binary or compiled from source). The app author 
>> decides when to update their dependencies, and updating those dependencies 
>> will produce new warnings/errors as the compiler notices new or deprecated 
>> cases. This is the current state of things and is completely orthogonal to 
>> the entire discussion.
> 
> This keeps sneaking into discussions and I hope to have it formalized in a 
> proposal soon. On the library side, we do want to make a distinction between 
> "needs binary compatibility" and "does not need binary compatibility". Why? 
> Because we can get much better performance if we know a 

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

2018-01-04 Thread Gwendal Roué via swift-evolution
Thanks for this extended rationale.

I would pin this post if I could. Or extend the "motivation" section of the 
proposal with it.

Gwendal

> Le 5 janv. 2018 à 01:38, Jordan Rose via swift-evolution 
>  a écrit :
> 
> Hi, Dave. You're right, all these points are worth addressing. I'm going to 
> go in sections.
> 
>> This whole “unexpected case” thing is only a problem when you’re linking 
>> libraries that are external to/shipped independently of your app. Right now, 
>> the *only* case where this might exist is Swift on the server. We *might* 
>> run in to this in the future once the ABI stabilizes and we have the Swift 
>> libraries shipping as part of iOS/macOS/Linux. Other than this, unexpected 
>> enum cases won’t really be a problem developers have to deal with.
> 
> 
> I wish this were the case, but it is not. Regardless of what we do for Swift 
> enums, we are in dire need of a fix for C enums. Today, if a C enum doesn't 
> have one of the expected values, the behavior is undefined in the C sense (as 
> in, type-unsafe, memory-unsafe, may invoke functions that shouldn't be 
> invoked, may not invoke functions that should be invoked, etc).
> 
> Obviously that's an unacceptable state of affairs; even without this proposal 
> we would fix it so that the program will deterministically trap instead. This 
> isn't perfect because it results in a (tiny) performance and code size hit 
> compared to C, but it's better than leaving such a massive hole in Swift's 
> safety story.
> 
> The trouble is that many enums—maybe even most enums—in the Apple SDK really 
> are expected to grow new cases, and the Apple API authors rely on this. Many 
> of those—probably most of them—are the ones that Brent Royal-Gordon described 
> as "opaque inputs", like UIViewAnimationTransition, which you're unlikely to 
> switch over but which the compiler should handle correctly if you do. Then 
> there are the murkier ones like SKPaymentTransactionState.
> 
> I'm going to come dangerously close to criticizing Apple and say I have a lot 
> of sympathy for third-party developers in the SKPaymentTransactionState case. 
> As Karl Wagner said, there wasn't really any way an existing app could handle 
> that case well, even if they had written an 'unknown case' handler. So what 
> could the StoreKit folks have done instead? They can't tell themselves 
> whether your app supports the new case, other than the heavy-handed "check 
> what SDK they compiled against" that ignores the possibility of embedded 
> binary frameworks. So maybe they should have added a property 
> "supportsDeferredState" or something that would have to be set before the new 
> state was returned.
> 
> (I'll pause to say I don't know what consideration went into this API and I'm 
> going to avoid looking it up to avoid perjury. This is all hypothetical, for 
> the next API that needs to add a case.)
> 
> Let's say we go with that, a property that controls whether the new case is 
> ever passed to third-party code. Now the new case exists, and new code needs 
> to switch over it. At the same time, old code needs to continue working. The 
> new enum case exists, and so even if it shouldn't escape into old code that 
> doesn't know how to handle it, the behavior needs to be defined if it does. 
> Furthermore, the old code needs to continue working without source changes, 
> because updating to a new SDK must not break existing code. (It can introduce 
> new warnings, but even that is something that should be considered carefully.)
> 
> So: this proposal is designed to handle the use cases both for Swift library 
> authors to come and for C APIs today, and in particular Apple's Objective-C 
> SDKs and how they've evolved historically.
> 
> 
> There's another really interesting point in your message, which Karl, Drew 
> Crawford, and others also touched on.
> 
>> Teaching the compiler/checker/whatever about the linking semantics of 
>> modules. For modules that are packaged inside the final built product, there 
>> is no need to deal with any unexpected cases, because we already have the 
>> exhaustiveness check appropriate for that scenario (regardless of whether 
>> the module is shipped as a binary or compiled from source). The app author 
>> decides when to update their dependencies, and updating those dependencies 
>> will produce new warnings/errors as the compiler notices new or deprecated 
>> cases. This is the current state of things and is completely orthogonal to 
>> the entire discussion.
> 
> This keeps sneaking into discussions and I hope to have it formalized in a 
> proposal soon. On the library side, we do want to make a distinction between 
> "needs binary compatibility" and "does not need binary compatibility". Why? 
> Because we can get much better performance if we know a library is never 
> going to change. A class will not acquire new dynamic-dispatch members; a 
> stored property will not turn into a computed 

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

2018-01-04 Thread Jordan Rose via swift-evolution
Hi, Dave. You're right, all these points are worth addressing. I'm going to go 
in sections.

> This whole “unexpected case” thing is only a problem when you’re linking 
> libraries that are external to/shipped independently of your app. Right now, 
> the *only* case where this might exist is Swift on the server. We *might* run 
> in to this in the future once the ABI stabilizes and we have the Swift 
> libraries shipping as part of iOS/macOS/Linux. Other than this, unexpected 
> enum cases won’t really be a problem developers have to deal with.


I wish this were the case, but it is not. Regardless of what we do for Swift 
enums, we are in dire need of a fix for C enums. Today, if a C enum doesn't 
have one of the expected values, the behavior is undefined in the C sense (as 
in, type-unsafe, memory-unsafe, may invoke functions that shouldn't be invoked, 
may not invoke functions that should be invoked, etc).

Obviously that's an unacceptable state of affairs; even without this proposal 
we would fix it so that the program will deterministically trap instead. This 
isn't perfect because it results in a (tiny) performance and code size hit 
compared to C, but it's better than leaving such a massive hole in Swift's 
safety story.

The trouble is that many enums—maybe even most enums—in the Apple SDK really 
are expected to grow new cases, and the Apple API authors rely on this. Many of 
those—probably most of them—are the ones that Brent Royal-Gordon described as 
"opaque inputs", like UIViewAnimationTransition, which you're unlikely to 
switch over but which the compiler should handle correctly if you do. Then 
there are the murkier ones like SKPaymentTransactionState.

I'm going to come dangerously close to criticizing Apple and say I have a lot 
of sympathy for third-party developers in the SKPaymentTransactionState case. 
As Karl Wagner said, there wasn't really any way an existing app could handle 
that case well, even if they had written an 'unknown case' handler. So what 
could the StoreKit folks have done instead? They can't tell themselves whether 
your app supports the new case, other than the heavy-handed "check what SDK 
they compiled against" that ignores the possibility of embedded binary 
frameworks. So maybe they should have added a property "supportsDeferredState" 
or something that would have to be set before the new state was returned.

(I'll pause to say I don't know what consideration went into this API and I'm 
going to avoid looking it up to avoid perjury. This is all hypothetical, for 
the next API that needs to add a case.)

Let's say we go with that, a property that controls whether the new case is 
ever passed to third-party code. Now the new case exists, and new code needs to 
switch over it. At the same time, old code needs to continue working. The new 
enum case exists, and so even if it shouldn't escape into old code that doesn't 
know how to handle it, the behavior needs to be defined if it does. 
Furthermore, the old code needs to continue working without source changes, 
because updating to a new SDK must not break existing code. (It can introduce 
new warnings, but even that is something that should be considered carefully.)

So: this proposal is designed to handle the use cases both for Swift library 
authors to come and for C APIs today, and in particular Apple's Objective-C 
SDKs and how they've evolved historically.


There's another really interesting point in your message, which Karl, Drew 
Crawford, and others also touched on.

> Teaching the compiler/checker/whatever about the linking semantics of 
> modules. For modules that are packaged inside the final built product, there 
> is no need to deal with any unexpected cases, because we already have the 
> exhaustiveness check appropriate for that scenario (regardless of whether the 
> module is shipped as a binary or compiled from source). The app author 
> decides when to update their dependencies, and updating those dependencies 
> will produce new warnings/errors as the compiler notices new or deprecated 
> cases. This is the current state of things and is completely orthogonal to 
> the entire discussion.

This keeps sneaking into discussions and I hope to have it formalized in a 
proposal soon. On the library side, we do want to make a distinction between 
"needs binary compatibility" and "does not need binary compatibility". Why? 
Because we can get much better performance if we know a library is never going 
to change. A class will not acquire new dynamic-dispatch members; a stored 
property will not turn into a computed property; a struct will not gain new 
stored properties. None of those things affect how client code is written, but 
they do affect what happens at run-time.

Okay, so should we use this as an indicator of whether an enum can grow new 
cases? (I'm going to ignore C libraries in this section, both because they 
don't have this distinction and because they can always lie anyway.)

- If a 

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

2018-01-04 Thread Nevin Brackett-Rozinsky via swift-evolution
On Thu, Jan 4, 2018 at 8:23 AM, Brent Royal-Gordon via swift-evolution <
swift-evolution@swift.org> wrote:

> On Jan 3, 2018, at 10:02 AM, Dave DeLong via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> 1️⃣ a @frozen/@tangled/@moana attribute for enums that’s only consulted on
> externally-linked modules
>
>
> Naming is serious business, Dave. Let it go.
>


Since the attribute means, “Don’t worry about new cases, this enum won’t
change for the rest of its days,” the optimal spelling is clearly
@hakunaMatata

We do still need a way for multi-module apps to work problem-free though.

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


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

2018-01-04 Thread Brent Royal-Gordon via swift-evolution
> On Jan 3, 2018, at 10:02 AM, Dave DeLong via swift-evolution 
>  wrote:
> 
> 1️⃣ a @frozen/@tangled/@moana attribute for enums that’s only consulted on 
> externally-linked modules


Naming is serious business, Dave. Let it go.

*ducks*

-- 
Brent Royal-Gordon
Architechies

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


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

2018-01-03 Thread Xiaodi Wu via swift-evolution
As has already been said, “case unknown” is source-breaking because it
conflicts with any real cases named “unknown”; “\unknown” looks like a key
path but isn’t, and I wonder if it would potentially conflict with existing
key paths.

In any case, my point was not to bikeshed the “unknown” part, but to ask
whether any consideration had been made to have the feature presented as a
flavor of default instead of a flavor of case.

On Wed, Jan 3, 2018 at 23:57 Cheyo Jimenez  wrote:

>
>
> On Jan 3, 2018, at 6:52 PM, Xiaodi Wu via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> This is a very nice revision. One bikeshedding thought:
>
> Since "unknown case" is presented as a special kind of "default", can't be
> mixed with "default", and can't be used in case patterns, why not "default
> unknown" (or "unknown default") instead of "unknown case"?
>
>
> `case _ :` is already a special case of default.
> I’d rather have `case unknown :`
> `unknown case :` is weird because of the order of `case`.
>
> Another alternative is `case \unknown :`
> `\unknown` would also allow pattern matching.
>
>
>
>
>
> On Wed, Jan 3, 2018 at 8:05 PM, Jordan Rose via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> On Jan 2, 2018, at 18:07, Jordan Rose  wrote:
>>
>> [Proposal:
>> https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md
>> ]
>>
>> Whew! Thanks for your feedback, everyone. On the lighter side of
>> feedback—naming things—it seems that most people seem to like '*@frozen*',
>> and that does in fact have the connotations we want it to have. I like it
>> too.
>>
>> More seriously, this discussion has convinced me that it's worth
>> including what the proposal discusses as a *'future' case*. The key
>> point that swayed me is that this can produce a *warning* when the
>> switch is missing a case rather than an *error,* which both provides the
>> necessary compiler feedback to update your code and allows your
>> dependencies to continue compiling when you update to a newer SDK. I know
>> people on both sides won't be 100% satisfied with this, but does it seem
>> like a reasonable compromise?
>>
>> The next question is how to spell it. I'm leaning towards `unexpected
>> case:`, which (a) is backwards-compatible, and (b) also handles "private
>> cases", either the fake kind that you can do in C (as described in the
>> proposal), or some real feature we might add to Swift some day. `unknown
>> case:` isn't bad either.
>>
>> I too would like to just do `unknown:` or `unexpected:` but that's
>> technically a source-breaking change:
>>
>> switch foo {
>> case bar:
>>   unknown:
>>   while baz() {
>> while garply() {
>>   if quux() {
>> break unknown
>>   }
>> }
>>   }
>> }
>>
>>
>> Another downside of the `unexpected case:` spelling is that it doesn't
>> work as part of a larger pattern. I don't have a good answer for that one,
>> but perhaps it's acceptable for now.
>>
>> I'll write up a revision of the proposal soon and make sure the core team
>> gets my recommendation when they discuss the results of the review.
>>
>> ---
>>
>> I'll respond to a few of the more intricate discussions tomorrow,
>> including the syntax of putting a new declaration inside the enum rather
>> than outside. Thank you again, everyone, and happy new year!
>>
>>
>> I ended up doing these in the opposite order, writing up the new proposal
>> first and not yet responding to the discussion that's further out. You can
>> read my revisions at https://github.com/apple/swift-evolution/pull/777.
>>
>> In particular, I want to at least address:
>> - Dave D and Drew C's points about versioned libraries / linking
>> semantics of modules.
>> - Jason M's point about migration
>> and I'll do one more pass over the thread to see if there's anything else
>> I didn't address directly. (That doesn't mean everyone who disagrees, just
>> messages where I think there's more I can do to explain why the proposal is
>> the way it is.)
>>
>> Jordan
>>
>> P.S. Enjoying the Disney references. Thanks, Nevin and Dave. :-)
>>
>> ___
>> 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


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

2018-01-03 Thread Cheyo Jimenez via swift-evolution


> On Jan 3, 2018, at 6:52 PM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> This is a very nice revision. One bikeshedding thought:
> 
> Since "unknown case" is presented as a special kind of "default", can't be 
> mixed with "default", and can't be used in case patterns, why not "default 
> unknown" (or "unknown default") instead of "unknown case"?

`case _ :` is already a special case of default. 
I’d rather have `case unknown :`
`unknown case :` is weird because of the order of `case`. 

Another alternative is `case \unknown :`
`\unknown` would also allow pattern matching. 



> 
> 
> On Wed, Jan 3, 2018 at 8:05 PM, Jordan Rose via swift-evolution 
>  wrote:
>>> On Jan 2, 2018, at 18:07, Jordan Rose  wrote:
>>> 
>>> [Proposal: 
>>> https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md]
>>> 
>>> Whew! Thanks for your feedback, everyone. On the lighter side of 
>>> feedback—naming things—it seems that most people seem to like '@frozen', 
>>> and that does in fact have the connotations we want it to have. I like it 
>>> too.
>>> 
>>> More seriously, this discussion has convinced me that it's worth including 
>>> what the proposal discusses as a 'future' case. The key point that swayed 
>>> me is that this can produce a warning when the switch is missing a case 
>>> rather than an error, which both provides the necessary compiler feedback 
>>> to update your code and allows your dependencies to continue compiling when 
>>> you update to a newer SDK. I know people on both sides won't be 100% 
>>> satisfied with this, but does it seem like a reasonable compromise?
>>> 
>>> The next question is how to spell it. I'm leaning towards `unexpected 
>>> case:`, which (a) is backwards-compatible, and (b) also handles "private 
>>> cases", either the fake kind that you can do in C (as described in the 
>>> proposal), or some real feature we might add to Swift some day. `unknown 
>>> case:` isn't bad either.
>>> 
>>> I too would like to just do `unknown:` or `unexpected:` but that's 
>>> technically a source-breaking change:
>>> 
>>> switch foo {
>>> case bar:
>>>   unknown:
>>>   while baz() {
>>> while garply() {
>>>   if quux() {
>>> break unknown
>>>   }
>>> }
>>>   }
>>> }
>>> 
>>> Another downside of the `unexpected case:` spelling is that it doesn't work 
>>> as part of a larger pattern. I don't have a good answer for that one, but 
>>> perhaps it's acceptable for now.
>>> 
>>> I'll write up a revision of the proposal soon and make sure the core team 
>>> gets my recommendation when they discuss the results of the review.
>>> 
>>> ---
>>> 
>>> I'll respond to a few of the more intricate discussions tomorrow, including 
>>> the syntax of putting a new declaration inside the enum rather than 
>>> outside. Thank you again, everyone, and happy new year!
>> 
>> I ended up doing these in the opposite order, writing up the new proposal 
>> first and not yet responding to the discussion that's further out. You can 
>> read my revisions at https://github.com/apple/swift-evolution/pull/777.
>> 
>> In particular, I want to at least address:
>> - Dave D and Drew C's points about versioned libraries / linking semantics 
>> of modules.
>> - Jason M's point about migration
>> and I'll do one more pass over the thread to see if there's anything else I 
>> didn't address directly. (That doesn't mean everyone who disagrees, just 
>> messages where I think there's more I can do to explain why the proposal is 
>> the way it is.)
>> 
>> Jordan
>> 
>> P.S. Enjoying the Disney references. Thanks, Nevin and Dave. :-)
>> 
>> ___
>> 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


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

2018-01-03 Thread Xiaodi Wu via swift-evolution
This is a very nice revision. One bikeshedding thought:

Since "unknown case" is presented as a special kind of "default", can't be
mixed with "default", and can't be used in case patterns, why not "default
unknown" (or "unknown default") instead of "unknown case"?


On Wed, Jan 3, 2018 at 8:05 PM, Jordan Rose via swift-evolution <
swift-evolution@swift.org> wrote:

> On Jan 2, 2018, at 18:07, Jordan Rose  wrote:
>
> [Proposal: https://github.com/apple/swift-evolution/blob/
> master/proposals/0192-non-exhaustive-enums.md]
>
> Whew! Thanks for your feedback, everyone. On the lighter side of
> feedback—naming things—it seems that most people seem to like '*@frozen*',
> and that does in fact have the connotations we want it to have. I like it
> too.
>
> More seriously, this discussion has convinced me that it's worth including
> what the proposal discusses as a *'future' case*. The key point that
> swayed me is that this can produce a *warning* when the switch is missing
> a case rather than an *error,* which both provides the necessary compiler
> feedback to update your code and allows your dependencies to continue
> compiling when you update to a newer SDK. I know people on both sides won't
> be 100% satisfied with this, but does it seem like a reasonable compromise?
>
> The next question is how to spell it. I'm leaning towards `unexpected
> case:`, which (a) is backwards-compatible, and (b) also handles "private
> cases", either the fake kind that you can do in C (as described in the
> proposal), or some real feature we might add to Swift some day. `unknown
> case:` isn't bad either.
>
> I too would like to just do `unknown:` or `unexpected:` but that's
> technically a source-breaking change:
>
> switch foo {
> case bar:
>   unknown:
>   while baz() {
> while garply() {
>   if quux() {
> break unknown
>   }
> }
>   }
> }
>
>
> Another downside of the `unexpected case:` spelling is that it doesn't
> work as part of a larger pattern. I don't have a good answer for that one,
> but perhaps it's acceptable for now.
>
> I'll write up a revision of the proposal soon and make sure the core team
> gets my recommendation when they discuss the results of the review.
>
> ---
>
> I'll respond to a few of the more intricate discussions tomorrow,
> including the syntax of putting a new declaration inside the enum rather
> than outside. Thank you again, everyone, and happy new year!
>
>
> I ended up doing these in the opposite order, writing up the new proposal
> first and not yet responding to the discussion that's further out. You can
> read my revisions at https://github.com/apple/swift-evolution/pull/777.
>
> In particular, I want to at least address:
> - Dave D and Drew C's points about versioned libraries / linking semantics
> of modules.
> - Jason M's point about migration
> and I'll do one more pass over the thread to see if there's anything else
> I didn't address directly. (That doesn't mean everyone who disagrees, just
> messages where I think there's more I can do to explain why the proposal is
> the way it is.)
>
> Jordan
>
> P.S. Enjoying the Disney references. Thanks, Nevin and Dave. :-)
>
> ___
> 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


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

2018-01-03 Thread Jordan Rose via swift-evolution
> On Jan 2, 2018, at 18:07, Jordan Rose  wrote:
> 
> [Proposal: 
> https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md
>  
> ]
> 
> Whew! Thanks for your feedback, everyone. On the lighter side of 
> feedback—naming things—it seems that most people seem to like '@frozen', and 
> that does in fact have the connotations we want it to have. I like it too.
> 
> More seriously, this discussion has convinced me that it's worth including 
> what the proposal discusses as a 'future' case. The key point that swayed me 
> is that this can produce a warning when the switch is missing a case rather 
> than an error, which both provides the necessary compiler feedback to update 
> your code and allows your dependencies to continue compiling when you update 
> to a newer SDK. I know people on both sides won't be 100% satisfied with 
> this, but does it seem like a reasonable compromise?
> 
> The next question is how to spell it. I'm leaning towards `unexpected case:`, 
> which (a) is backwards-compatible, and (b) also handles "private cases", 
> either the fake kind that you can do in C (as described in the proposal), or 
> some real feature we might add to Swift some day. `unknown case:` isn't bad 
> either.
> 
> I too would like to just do `unknown:` or `unexpected:` but that's 
> technically a source-breaking change:
> 
> switch foo {
> case bar:
>   unknown:
>   while baz() {
> while garply() {
>   if quux() {
> break unknown
>   }
> }
>   }
> }
> 
> Another downside of the `unexpected case:` spelling is that it doesn't work 
> as part of a larger pattern. I don't have a good answer for that one, but 
> perhaps it's acceptable for now.
> 
> I'll write up a revision of the proposal soon and make sure the core team 
> gets my recommendation when they discuss the results of the review.
> 
> ---
> 
> I'll respond to a few of the more intricate discussions tomorrow, including 
> the syntax of putting a new declaration inside the enum rather than outside. 
> Thank you again, everyone, and happy new year!

I ended up doing these in the opposite order, writing up the new proposal first 
and not yet responding to the discussion that's further out. You can read my 
revisions at https://github.com/apple/swift-evolution/pull/777.

In particular, I want to at least address:
- Dave D and Drew C's points about versioned libraries / linking semantics of 
modules.
- Jason M's point about migration
and I'll do one more pass over the thread to see if there's anything else I 
didn't address directly. (That doesn't mean everyone who disagrees, just 
messages where I think there's more I can do to explain why the proposal is the 
way it is.)

Jordan

P.S. Enjoying the Disney references. Thanks, Nevin and Dave. :-)___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2018-01-03 Thread Karl Wagner via swift-evolution


> On 3. Jan 2018, at 18:49, Dave DeLong via swift-evolution 
>  wrote:
> 
> 
> 
>> On Jan 3, 2018, at 10:36 AM, Matthew Johnson > > wrote:
>> 
>> 
>>> On Jan 3, 2018, at 11:07 AM, Dave DeLong via swift-evolution 
>>> > wrote:
>>> 
>>> IMO this is still too large of a hammer for this problem.
>>> 
>>> This whole “unexpected case” thing is only a problem when you’re linking 
>>> libraries that are external to/shipped independently of your app. Right 
>>> now, the *only* case where this might exist is Swift on the server. We 
>>> *might* run in to this in the future once the ABI stabilizes and we have 
>>> the Swift libraries shipping as part of iOS/macOS/Linux. Other than this, 
>>> unexpected enum cases won’t really be a problem developers have to deal 
>>> with.
>>> 
>>> Because this will be such a relatively rare problem, I feel like a syntax 
>>> change like what’s being proposed is a too-massive hammer for such a small 
>>> nail.
>>> 
>>> What feels far more appropriate is:
>>> 
>>> ️ Teaching the compiler/checker/whatever about the linking semantics of 
>>> modules. For modules that are packaged inside the final built product, 
>>> there is no need to deal with any unexpected cases, because we already have 
>>> the exhaustiveness check appropriate for that scenario (regardless of 
>>> whether the module is shipped as a binary or compiled from source). The app 
>>> author decides when to update their dependencies, and updating those 
>>> dependencies will produce new warnings/errors as the compiler notices new 
>>> or deprecated cases. This is the current state of things and is completely 
>>> orthogonal to the entire discussion.
>> 
>> John McCall sketched out a vision of what a solution to this might look like 
>> here: 
>> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20171218/042333.html
>>  
>> .
>>  
>> 
>>> 
>>> and
>>> 
>>> ️ Adding an attribute (@frozen, @tangled, @moana, @whatever) that can be 
>>> used to decorate an enum declaration. This attribute would only need to be 
>>> consulted on enums where the compiler can determine that the module will 
>>> *not* be part of the final built product. (Ie, it’s an “external” module, 
>>> in my nomenclature). This, then, is a module that can update independently 
>>> of the final app, and therefore there are two possible cases:
>>> 
>>> 1️⃣ If the enum is decorated with @frozen, then I, as an app author, 
>>> have the assurance that the enum case will not change in future releases of 
>>> the library, and I can safely switch on all known cases and not have to 
>>> provide a default case. 
>>> 
>>> 2️⃣ If the enum is NOT decorated with @frozen, then I, as an app 
>>> author, have to account for the possibility that the module may update from 
>>> underneath my app, and I have to handle an unknown case. This is simple: 
>>> the compiler should require me to add a “default:” case to my switch 
>>> statement. This warning is produced IFF: the enum is coming from an 
>>> external module, and the enum is not decorated with @frozen.
>> 
>> This does not help people who need to write a switch statement over an enum 
>> vended by a module that ships with the OS keep their code up to date as the 
>> module adds new cases. I find the example of `SKPaymentTransactionState` 
>> provided by Brent Royal-Gordon here: 
>> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170904/039512.html
>>  
>> 
>>  to be compelling.  There are rare but legitimate reasons to switch over all 
>> known cases of a non-@frozen enum that ship with the OS.  These use cases 
>> deserve proper language support.  I think Jordan’s solution strikes a good 
>> balance.
> 
> I disagree that more is needed. In the case of the transaction state, it 
> should not be marked as @moana, and so the compiler would force you to add a 
> “default” case to your switch statements. The switch statements would still 
> be exhaustive with all known cases (if you choose to handle all known cases), 
> but you’d still need a default case because there might be new transaction 
> states in the future.
> 
> In those cases, your app could decide what to do, if that’s possible at all. 
> Maybe there’s other transaction information you could introspect to determine 
> if it succeeded or is still pending or whatever, and then your app could 
> respond as you see fit.
> 
> Dave
> ___
> swift-evolution mailing list
> swift-evolution@swift.org 
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> 
So here’s something that I’m 

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

2018-01-03 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Jan 3, 2018, at 12:20 PM, Dave DeLong  wrote:
> 
> 
> 
>>> On Jan 3, 2018, at 11:09 AM, Matthew Johnson  wrote:
>>> 
>>> 
 On Jan 3, 2018, at 12:02 PM, Dave DeLong  wrote:
 
 
 
 On Jan 3, 2018, at 10:58 AM, Kevin Nattinger  wrote:
 
>>> [...]
>>> 2️⃣ If the enum is NOT decorated with @frozen, then I, as an 
>>> app author, have to account for the possibility that the module may 
>>> update from underneath my app, and I have to handle an unknown case. 
>>> This is simple: the compiler should require me to add a “default:” case 
>>> to my switch statement. This warning is produced IFF: the enum is 
>>> coming from an external module, and the enum is not decorated with 
>>> @frozen.
>> 
>> This does not help people who need to write a switch statement over an 
>> enum vended by a module that ships with the OS keep their code up to 
>> date as the module adds new cases. I find the example of 
>> `SKPaymentTransactionState` provided by Brent Royal-Gordon here: 
>> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170904/039512.html
>>  to be compelling.  There are rare but legitimate reasons to switch over 
>> all known cases of a non-@frozen enum that ship with the OS.  These use 
>> cases deserve proper language support.  I think Jordan’s solution 
>> strikes a good balance.
> 
> I disagree that more is needed. In the case of the transaction state, it 
> should not be marked as @moana, and so the compiler would force you to 
> add a “default” case to your switch statements. The switch statements 
> would still be exhaustive with all known cases (if you choose to handle 
> all known cases), but you’d still need a default case because there might 
> be new transaction states in the future.
 
 And then you don't get the compiler error/warning when you start compiling 
 against the next OS update that changes the enum. That is an absolutely 
 unacceptable loss of compile-time checks.
>>> 
>>> Ah, that’s an excellent point! Thanks for pointing that out.
>>> 
>>> In that case, I revise my proposal:
>>> 
>>> 1️⃣ a @frozen/@tangled/@moana attribute for enums that’s only consulted on 
>>> externally-linked modules
>>> 2️⃣ a “future case:” statement that’s only required on externally-linked, 
>>> non-@moana enums. That way, if the enum adds a new case in the future, 
>>> you’ll still get a switch warning about handling all the cases. And then if 
>>> you want, you could “fallthrough” from this to a “default” case, or 
>>> vice-versa, or have separate implementations.
>> 
>> It sounds to me like the main thing you’re unhappy about is having to deal 
>> with unknown cases when you have a source dependency that you always build 
>> and ship with an app.  I don’t think anyone is happy with that situation.  
> 
> That’s definitely part of it. The other main part is that I’m hugely 
> resistant to adding extraneous syntax when a solution that’s simpler for 
> users exists.

That’s fair.  If we didn’t have a compelling motivating example I would be more 
reluctant about the need to add syntax here, but we do have such an example.

> 
>> Did you take a look at the sketch of a solution provided by John McCall?  
>> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20171218/042333.html
> 
> I’ve read that email several times and don’t understand how it relates.

I should have also linked to his previous email.  Does this one help clarify 
what he has in mind?  
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20171218/042329.html

> 
> Dave
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2018-01-03 Thread Dave DeLong via swift-evolution


> On Jan 3, 2018, at 11:09 AM, Matthew Johnson  wrote:
> 
>> 
>> On Jan 3, 2018, at 12:02 PM, Dave DeLong > > wrote:
>> 
>> 
>> 
>>> On Jan 3, 2018, at 10:58 AM, Kevin Nattinger >> > wrote:
>>> 
>> [...]
>>  2️⃣ If the enum is NOT decorated with @frozen, then I, as an app 
>> author, have to account for the possibility that the module may update 
>> from underneath my app, and I have to handle an unknown case. This is 
>> simple: the compiler should require me to add a “default:” case to my 
>> switch statement. This warning is produced IFF: the enum is coming from 
>> an external module, and the enum is not decorated with @frozen.
> 
> This does not help people who need to write a switch statement over an 
> enum vended by a module that ships with the OS keep their code up to date 
> as the module adds new cases. I find the example of 
> `SKPaymentTransactionState` provided by Brent Royal-Gordon here: 
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170904/039512.html
>  
> 
>  to be compelling.  There are rare but legitimate reasons to switch over 
> all known cases of a non-@frozen enum that ship with the OS.  These use 
> cases deserve proper language support.  I think Jordan’s solution strikes 
> a good balance.
 
 I disagree that more is needed. In the case of the transaction state, it 
 should not be marked as @moana, and so the compiler would force you to add 
 a “default” case to your switch statements. The switch statements would 
 still be exhaustive with all known cases (if you choose to handle all 
 known cases), but you’d still need a default case because there might be 
 new transaction states in the future.
>>> 
>>> And then you don't get the compiler error/warning when you start compiling 
>>> against the next OS update that changes the enum. That is an absolutely 
>>> unacceptable loss of compile-time checks.
>> 
>> Ah, that’s an excellent point! Thanks for pointing that out.
>> 
>> In that case, I revise my proposal:
>> 
>> 1️⃣ a @frozen/@tangled/@moana attribute for enums that’s only consulted on 
>> externally-linked modules
>> 2️⃣ a “future case:” statement that’s only required on externally-linked, 
>> non-@moana enums. That way, if the enum adds a new case in the future, 
>> you’ll still get a switch warning about handling all the cases. And then if 
>> you want, you could “fallthrough” from this to a “default” case, or 
>> vice-versa, or have separate implementations.
> 
> It sounds to me like the main thing you’re unhappy about is having to deal 
> with unknown cases when you have a source dependency that you always build 
> and ship with an app.  I don’t think anyone is happy with that situation.  

That’s definitely part of it. The other main part is that I’m hugely resistant 
to adding extraneous syntax when a solution that’s simpler for users exists.

> Did you take a look at the sketch of a solution provided by John McCall?  
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20171218/042333.html
>  
> 
I’ve read that email several times and don’t understand how it relates.

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


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

2018-01-03 Thread Matthew Johnson via swift-evolution

> On Jan 3, 2018, at 12:02 PM, Dave DeLong  wrote:
> 
> 
> 
>> On Jan 3, 2018, at 10:58 AM, Kevin Nattinger > > wrote:
>> 
> [...]
>   2️⃣ If the enum is NOT decorated with @frozen, then I, as an app 
> author, have to account for the possibility that the module may update 
> from underneath my app, and I have to handle an unknown case. This is 
> simple: the compiler should require me to add a “default:” case to my 
> switch statement. This warning is produced IFF: the enum is coming from 
> an external module, and the enum is not decorated with @frozen.
 
 This does not help people who need to write a switch statement over an 
 enum vended by a module that ships with the OS keep their code up to date 
 as the module adds new cases. I find the example of 
 `SKPaymentTransactionState` provided by Brent Royal-Gordon here: 
 https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170904/039512.html
  
 
  to be compelling.  There are rare but legitimate reasons to switch over 
 all known cases of a non-@frozen enum that ship with the OS.  These use 
 cases deserve proper language support.  I think Jordan’s solution strikes 
 a good balance.
>>> 
>>> I disagree that more is needed. In the case of the transaction state, it 
>>> should not be marked as @moana, and so the compiler would force you to add 
>>> a “default” case to your switch statements. The switch statements would 
>>> still be exhaustive with all known cases (if you choose to handle all known 
>>> cases), but you’d still need a default case because there might be new 
>>> transaction states in the future.
>> 
>> And then you don't get the compiler error/warning when you start compiling 
>> against the next OS update that changes the enum. That is an absolutely 
>> unacceptable loss of compile-time checks.
> 
> Ah, that’s an excellent point! Thanks for pointing that out.
> 
> In that case, I revise my proposal:
> 
> 1️⃣ a @frozen/@tangled/@moana attribute for enums that’s only consulted on 
> externally-linked modules
> 2️⃣ a “future case:” statement that’s only required on externally-linked, 
> non-@moana enums. That way, if the enum adds a new case in the future, you’ll 
> still get a switch warning about handling all the cases. And then if you 
> want, you could “fallthrough” from this to a “default” case, or vice-versa, 
> or have separate implementations.

It sounds to me like the main thing you’re unhappy about is having to deal with 
unknown cases when you have a source dependency that you always build and ship 
with an app.  I don’t think anyone is happy with that situation.  Did you take 
a look at the sketch of a solution provided by John McCall?  
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20171218/042333.html
 

> 
> Dave
> 
>> 
>>> 
>>> In those cases, your app could decide what to do, if that’s possible at 
>>> all. Maybe there’s other transaction information you could introspect to 
>>> determine if it succeeded or is still pending or whatever, and then your 
>>> app could respond as you see fit.
>>> 
>>> Dave
>>> ___
>>> 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


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

2018-01-03 Thread Matthew Johnson via swift-evolution

> On Jan 3, 2018, at 11:49 AM, Dave DeLong  wrote:
> 
> 
> 
>> On Jan 3, 2018, at 10:36 AM, Matthew Johnson > > wrote:
>> 
>> 
>>> On Jan 3, 2018, at 11:07 AM, Dave DeLong via swift-evolution 
>>> > wrote:
>>> 
>>> IMO this is still too large of a hammer for this problem.
>>> 
>>> This whole “unexpected case” thing is only a problem when you’re linking 
>>> libraries that are external to/shipped independently of your app. Right 
>>> now, the *only* case where this might exist is Swift on the server. We 
>>> *might* run in to this in the future once the ABI stabilizes and we have 
>>> the Swift libraries shipping as part of iOS/macOS/Linux. Other than this, 
>>> unexpected enum cases won’t really be a problem developers have to deal 
>>> with.
>>> 
>>> Because this will be such a relatively rare problem, I feel like a syntax 
>>> change like what’s being proposed is a too-massive hammer for such a small 
>>> nail.
>>> 
>>> What feels far more appropriate is:
>>> 
>>> ️ Teaching the compiler/checker/whatever about the linking semantics of 
>>> modules. For modules that are packaged inside the final built product, 
>>> there is no need to deal with any unexpected cases, because we already have 
>>> the exhaustiveness check appropriate for that scenario (regardless of 
>>> whether the module is shipped as a binary or compiled from source). The app 
>>> author decides when to update their dependencies, and updating those 
>>> dependencies will produce new warnings/errors as the compiler notices new 
>>> or deprecated cases. This is the current state of things and is completely 
>>> orthogonal to the entire discussion.
>> 
>> John McCall sketched out a vision of what a solution to this might look like 
>> here: 
>> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20171218/042333.html
>>  
>> .
>>  
>> 
>>> 
>>> and
>>> 
>>> ️ Adding an attribute (@frozen, @tangled, @moana, @whatever) that can be 
>>> used to decorate an enum declaration. This attribute would only need to be 
>>> consulted on enums where the compiler can determine that the module will 
>>> *not* be part of the final built product. (Ie, it’s an “external” module, 
>>> in my nomenclature). This, then, is a module that can update independently 
>>> of the final app, and therefore there are two possible cases:
>>> 
>>> 1️⃣ If the enum is decorated with @frozen, then I, as an app author, 
>>> have the assurance that the enum case will not change in future releases of 
>>> the library, and I can safely switch on all known cases and not have to 
>>> provide a default case. 
>>> 
>>> 2️⃣ If the enum is NOT decorated with @frozen, then I, as an app 
>>> author, have to account for the possibility that the module may update from 
>>> underneath my app, and I have to handle an unknown case. This is simple: 
>>> the compiler should require me to add a “default:” case to my switch 
>>> statement. This warning is produced IFF: the enum is coming from an 
>>> external module, and the enum is not decorated with @frozen.
>> 
>> This does not help people who need to write a switch statement over an enum 
>> vended by a module that ships with the OS keep their code up to date as the 
>> module adds new cases. I find the example of `SKPaymentTransactionState` 
>> provided by Brent Royal-Gordon here: 
>> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170904/039512.html
>>  
>> 
>>  to be compelling.  There are rare but legitimate reasons to switch over all 
>> known cases of a non-@frozen enum that ship with the OS.  These use cases 
>> deserve proper language support.  I think Jordan’s solution strikes a good 
>> balance.
> 
> I disagree that more is needed. In the case of the transaction state, it 
> should not be marked as @moana, and so the compiler would force you to add a 
> “default” case to your switch statements. The switch statements would still 
> be exhaustive with all known cases (if you choose to handle all known cases), 
> but you’d still need a default case because there might be new transaction 
> states in the future.
> 
> In those cases, your app could decide what to do, if that’s possible at all. 
> Maybe there’s other transaction information you could introspect to determine 
> if it succeeded or is still pending or whatever, and then your app could 
> respond as you see fit.

SKPaymentTransactionState is an excellent motivating example for a better 
solution because it is crucial to update code to handle any new states 
accurately and promptly.  This is much easier to do with compiler assistance 
than without it. 

It is also an excellent motivating example because the API change is driven by 
a 

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

2018-01-03 Thread Dave DeLong via swift-evolution


> On Jan 3, 2018, at 10:58 AM, Kevin Nattinger  wrote:
> 
 [...]
2️⃣ If the enum is NOT decorated with @frozen, then I, as an app 
 author, have to account for the possibility that the module may update 
 from underneath my app, and I have to handle an unknown case. This is 
 simple: the compiler should require me to add a “default:” case to my 
 switch statement. This warning is produced IFF: the enum is coming from an 
 external module, and the enum is not decorated with @frozen.
>>> 
>>> This does not help people who need to write a switch statement over an enum 
>>> vended by a module that ships with the OS keep their code up to date as the 
>>> module adds new cases. I find the example of `SKPaymentTransactionState` 
>>> provided by Brent Royal-Gordon here: 
>>> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170904/039512.html
>>>  
>>> 
>>>  to be compelling.  There are rare but legitimate reasons to switch over 
>>> all known cases of a non-@frozen enum that ship with the OS.  These use 
>>> cases deserve proper language support.  I think Jordan’s solution strikes a 
>>> good balance.
>> 
>> I disagree that more is needed. In the case of the transaction state, it 
>> should not be marked as @moana, and so the compiler would force you to add a 
>> “default” case to your switch statements. The switch statements would still 
>> be exhaustive with all known cases (if you choose to handle all known 
>> cases), but you’d still need a default case because there might be new 
>> transaction states in the future.
> 
> And then you don't get the compiler error/warning when you start compiling 
> against the next OS update that changes the enum. That is an absolutely 
> unacceptable loss of compile-time checks.

Ah, that’s an excellent point! Thanks for pointing that out.

In that case, I revise my proposal:

1️⃣ a @frozen/@tangled/@moana attribute for enums that’s only consulted on 
externally-linked modules
2️⃣ a “future case:” statement that’s only required on externally-linked, 
non-@moana enums. That way, if the enum adds a new case in the future, you’ll 
still get a switch warning about handling all the cases. And then if you want, 
you could “fallthrough” from this to a “default” case, or vice-versa, or have 
separate implementations.

Dave

> 
>> 
>> In those cases, your app could decide what to do, if that’s possible at all. 
>> Maybe there’s other transaction information you could introspect to 
>> determine if it succeeded or is still pending or whatever, and then your app 
>> could respond as you see fit.
>> 
>> Dave
>> ___
>> 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


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

2018-01-03 Thread Kevin Nattinger via swift-evolution
>>> [...]
>>> 2️⃣ If the enum is NOT decorated with @frozen, then I, as an app 
>>> author, have to account for the possibility that the module may update from 
>>> underneath my app, and I have to handle an unknown case. This is simple: 
>>> the compiler should require me to add a “default:” case to my switch 
>>> statement. This warning is produced IFF: the enum is coming from an 
>>> external module, and the enum is not decorated with @frozen.
>> 
>> This does not help people who need to write a switch statement over an enum 
>> vended by a module that ships with the OS keep their code up to date as the 
>> module adds new cases. I find the example of `SKPaymentTransactionState` 
>> provided by Brent Royal-Gordon here: 
>> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170904/039512.html
>>  
>> 
>>  to be compelling.  There are rare but legitimate reasons to switch over all 
>> known cases of a non-@frozen enum that ship with the OS.  These use cases 
>> deserve proper language support.  I think Jordan’s solution strikes a good 
>> balance.
> 
> I disagree that more is needed. In the case of the transaction state, it 
> should not be marked as @moana, and so the compiler would force you to add a 
> “default” case to your switch statements. The switch statements would still 
> be exhaustive with all known cases (if you choose to handle all known cases), 
> but you’d still need a default case because there might be new transaction 
> states in the future.

And then you don't get the compiler error/warning when you start compiling 
against the next OS update that changes the enum. That is an absolutely 
unacceptable loss of compile-time checks.

> 
> In those cases, your app could decide what to do, if that’s possible at all. 
> Maybe there’s other transaction information you could introspect to determine 
> if it succeeded or is still pending or whatever, and then your app could 
> respond as you see fit.
> 
> Dave
> ___
> 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


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

2018-01-03 Thread Matthew Johnson via swift-evolution

> On Jan 3, 2018, at 11:47 AM, BJ Homer  wrote:
> 
> 
> 
>> On Jan 3, 2018, at 10:36 AM, Matthew Johnson via swift-evolution 
>> > wrote:
>> 
>> This does not help people who need to write a switch statement over an enum 
>> vended by a module that ships with the OS keep their code up to date as the 
>> module adds new cases. I find the example of `SKPaymentTransactionState` 
>> provided by Brent Royal-Gordon here: 
>> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170904/039512.html
>>  
>> 
>>  to be compelling.  There are rare but legitimate reasons to switch over all 
>> known cases of a non-@frozen enum that ship with the OS.  These use cases 
>> deserve proper language support.  I think Jordan’s solution strikes a good 
>> balance.
> 
> I agree that the SKPaymentTransactionState example is compelling. However, I 
> don’t understand what actual code a developer would put in the “unexpected 
> case:” clause. That enum is related to handling in-app purchases; it’s 
> expected that the app would react in some way to a transaction changing 
> state. What should the app do if the transaction enters an “unexpected” 
> state? Pop up an error to the user that the user can do nothing about? It’s 
> great to get a compiler warning about a case like when the developer builds 
> with the new SDK, but I don’t understand what the already-shipped app is 
> supposed to do in a case like this.
> 
> For the SKPaymentTransactionState case, at least, it seems like the library 
> needs to be responsible to only send known values to the client. Otherwise, 
> the app can have no idea what to do.

There is definitely not a good answer here.  Making the library responsible to 
only send known values is not a solution.  This type represents the state of an 
entity and it should do so as accurately as possible.  Sometimes a new state 
cannot be mapped to one of the previous states.  How would you have StoreKit 
handle the deferred state for old clients?

My position is that the situation is much worse for an app developer when they 
don’t even get the assistance of a compiler warning when updating to the new 
SDK.  App developers are sometimes forced to deal with unfortunate cases like 
this.  Any help the language can provide is appreciated.

> 
> -BJ

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


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

2018-01-03 Thread Dave DeLong via swift-evolution


> On Jan 3, 2018, at 10:36 AM, Matthew Johnson  wrote:
> 
> 
>> On Jan 3, 2018, at 11:07 AM, Dave DeLong via swift-evolution 
>> > wrote:
>> 
>> IMO this is still too large of a hammer for this problem.
>> 
>> This whole “unexpected case” thing is only a problem when you’re linking 
>> libraries that are external to/shipped independently of your app. Right now, 
>> the *only* case where this might exist is Swift on the server. We *might* 
>> run in to this in the future once the ABI stabilizes and we have the Swift 
>> libraries shipping as part of iOS/macOS/Linux. Other than this, unexpected 
>> enum cases won’t really be a problem developers have to deal with.
>> 
>> Because this will be such a relatively rare problem, I feel like a syntax 
>> change like what’s being proposed is a too-massive hammer for such a small 
>> nail.
>> 
>> What feels far more appropriate is:
>> 
>> ️ Teaching the compiler/checker/whatever about the linking semantics of 
>> modules. For modules that are packaged inside the final built product, there 
>> is no need to deal with any unexpected cases, because we already have the 
>> exhaustiveness check appropriate for that scenario (regardless of whether 
>> the module is shipped as a binary or compiled from source). The app author 
>> decides when to update their dependencies, and updating those dependencies 
>> will produce new warnings/errors as the compiler notices new or deprecated 
>> cases. This is the current state of things and is completely orthogonal to 
>> the entire discussion.
> 
> John McCall sketched out a vision of what a solution to this might look like 
> here: 
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20171218/042333.html
>  
> .
>  
> 
>> 
>> and
>> 
>> ️ Adding an attribute (@frozen, @tangled, @moana, @whatever) that can be 
>> used to decorate an enum declaration. This attribute would only need to be 
>> consulted on enums where the compiler can determine that the module will 
>> *not* be part of the final built product. (Ie, it’s an “external” module, in 
>> my nomenclature). This, then, is a module that can update independently of 
>> the final app, and therefore there are two possible cases:
>> 
>>  1️⃣ If the enum is decorated with @frozen, then I, as an app author, 
>> have the assurance that the enum case will not change in future releases of 
>> the library, and I can safely switch on all known cases and not have to 
>> provide a default case. 
>> 
>>  2️⃣ If the enum is NOT decorated with @frozen, then I, as an app 
>> author, have to account for the possibility that the module may update from 
>> underneath my app, and I have to handle an unknown case. This is simple: the 
>> compiler should require me to add a “default:” case to my switch statement. 
>> This warning is produced IFF: the enum is coming from an external module, 
>> and the enum is not decorated with @frozen.
> 
> This does not help people who need to write a switch statement over an enum 
> vended by a module that ships with the OS keep their code up to date as the 
> module adds new cases. I find the example of `SKPaymentTransactionState` 
> provided by Brent Royal-Gordon here: 
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170904/039512.html
>  
> 
>  to be compelling.  There are rare but legitimate reasons to switch over all 
> known cases of a non-@frozen enum that ship with the OS.  These use cases 
> deserve proper language support.  I think Jordan’s solution strikes a good 
> balance.

I disagree that more is needed. In the case of the transaction state, it should 
not be marked as @moana, and so the compiler would force you to add a “default” 
case to your switch statements. The switch statements would still be exhaustive 
with all known cases (if you choose to handle all known cases), but you’d still 
need a default case because there might be new transaction states in the future.

In those cases, your app could decide what to do, if that’s possible at all. 
Maybe there’s other transaction information you could introspect to determine 
if it succeeded or is still pending or whatever, and then your app could 
respond as you see fit.

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


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

2018-01-03 Thread BJ Homer via swift-evolution


> On Jan 3, 2018, at 10:36 AM, Matthew Johnson via swift-evolution 
>  wrote:
> 
> This does not help people who need to write a switch statement over an enum 
> vended by a module that ships with the OS keep their code up to date as the 
> module adds new cases. I find the example of `SKPaymentTransactionState` 
> provided by Brent Royal-Gordon here: 
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170904/039512.html
>  
> 
>  to be compelling.  There are rare but legitimate reasons to switch over all 
> known cases of a non-@frozen enum that ship with the OS.  These use cases 
> deserve proper language support.  I think Jordan’s solution strikes a good 
> balance.

I agree that the SKPaymentTransactionState example is compelling. However, I 
don’t understand what actual code a developer would put in the “unexpected 
case:” clause. That enum is related to handling in-app purchases; it’s expected 
that the app would react in some way to a transaction changing state. What 
should the app do if the transaction enters an “unexpected” state? Pop up an 
error to the user that the user can do nothing about? It’s great to get a 
compiler warning about a case like when the developer builds with the new SDK, 
but I don’t understand what the already-shipped app is supposed to do in a case 
like this.

For the SKPaymentTransactionState case, at least, it seems like the library 
needs to be responsible to only send known values to the client. Otherwise, the 
app can have no idea what to do.

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


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

2018-01-03 Thread Matthew Johnson via swift-evolution

> On Jan 3, 2018, at 11:07 AM, Dave DeLong via swift-evolution 
>  wrote:
> 
> IMO this is still too large of a hammer for this problem.
> 
> This whole “unexpected case” thing is only a problem when you’re linking 
> libraries that are external to/shipped independently of your app. Right now, 
> the *only* case where this might exist is Swift on the server. We *might* run 
> in to this in the future once the ABI stabilizes and we have the Swift 
> libraries shipping as part of iOS/macOS/Linux. Other than this, unexpected 
> enum cases won’t really be a problem developers have to deal with.
> 
> Because this will be such a relatively rare problem, I feel like a syntax 
> change like what’s being proposed is a too-massive hammer for such a small 
> nail.
> 
> What feels far more appropriate is:
> 
> ️ Teaching the compiler/checker/whatever about the linking semantics of 
> modules. For modules that are packaged inside the final built product, there 
> is no need to deal with any unexpected cases, because we already have the 
> exhaustiveness check appropriate for that scenario (regardless of whether the 
> module is shipped as a binary or compiled from source). The app author 
> decides when to update their dependencies, and updating those dependencies 
> will produce new warnings/errors as the compiler notices new or deprecated 
> cases. This is the current state of things and is completely orthogonal to 
> the entire discussion.

John McCall sketched out a vision of what a solution to this might look like 
here: 
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20171218/042333.html
 
.
 

> 
> and
> 
> ️ Adding an attribute (@frozen, @tangled, @moana, @whatever) that can be 
> used to decorate an enum declaration. This attribute would only need to be 
> consulted on enums where the compiler can determine that the module will 
> *not* be part of the final built product. (Ie, it’s an “external” module, in 
> my nomenclature). This, then, is a module that can update independently of 
> the final app, and therefore there are two possible cases:
> 
>   1️⃣ If the enum is decorated with @frozen, then I, as an app author, 
> have the assurance that the enum case will not change in future releases of 
> the library, and I can safely switch on all known cases and not have to 
> provide a default case. 
> 
>   2️⃣ If the enum is NOT decorated with @frozen, then I, as an app 
> author, have to account for the possibility that the module may update from 
> underneath my app, and I have to handle an unknown case. This is simple: the 
> compiler should require me to add a “default:” case to my switch statement. 
> This warning is produced IFF: the enum is coming from an external module, and 
> the enum is not decorated with @frozen.

This does not help people who need to write a switch statement over an enum 
vended by a module that ships with the OS keep their code up to date as the 
module adds new cases. I find the example of `SKPaymentTransactionState` 
provided by Brent Royal-Gordon here: 
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170904/039512.html
 

 to be compelling.  There are rare but legitimate reasons to switch over all 
known cases of a non-@frozen enum that ship with the OS.  These use cases 
deserve proper language support.  I think Jordan’s solution strikes a good 
balance.

> 
> 
> ==
> 
> With this proposal, we only have one thing to consider: the spelling of 
> @frozen/@moana/@whatever that we decorate enums in external modules with. 
> Other than that, the existing behavior we currently have is completely 
> capable of covering the possibilities: we just keep using a “default:” case 
> whenever the compiler can’t guarantee that we can be exhaustive in our 
> switching.
> 
> Where the real work would be is teaching the compiler about 
> internally-vs-externally linked modules.
> 
> Dave
> 
>> On Jan 2, 2018, at 7:07 PM, Jordan Rose via swift-evolution 
>> > wrote:
>> 
>> [Proposal: 
>> https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md
>>  
>> ]
>> 
>> Whew! Thanks for your feedback, everyone. On the lighter side of 
>> feedback—naming things—it seems that most people seem to like '@frozen', and 
>> that does in fact have the connotations we want it to have. I like it too.
>> 
>> More seriously, this discussion has convinced me that it's worth including 
>> what the proposal discusses as a 'future' case. The key point that swayed me 
>> is that this can produce a warning when the switch is missing a case rather 
>> than an error, which both provides the necessary 

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

2018-01-03 Thread Ben Rimmington via swift-evolution
> On 3 Jan 2018, at 02:07, Jordan Rose wrote:
> 
> [Proposal: 
> https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md
>  
> ]
> 
> Whew! Thanks for your feedback, everyone. On the lighter side of 
> feedback—naming things—it seems that most people seem to like '@frozen', and 
> that does in fact have the connotations we want it to have. I like it too.

Should there be a new Clang attribute for "frozen" enums? Then the existing 
`__attribute__((enum_extensibility(closed)))` would only prevent "private" 
cases (and not future "public" cases).



> More seriously, this discussion has convinced me that it's worth including 
> what the proposal discusses as a 'future' case. The key point that swayed me 
> is that this can produce a warning when the switch is missing a case rather 
> than an error, which both provides the necessary compiler feedback to update 
> your code and allows your dependencies to continue compiling when you update 
> to a newer SDK. I know people on both sides won't be 100% satisfied with 
> this, but does it seem like a reasonable compromise?
> 
> The next question is how to spell it. I'm leaning towards `unexpected case:`, 
> which (a) is backwards-compatible, and (b) also handles "private cases", 
> either the fake kind that you can do in C (as described in the proposal), or 
> some real feature we might add to Swift some day. `unknown case:` isn't bad 
> either.

You might end up with `case .unknown:` and `unknown case:` in the same switch.

e.g. 

```
switch mediaType {
case .image, .video, .audio:
break
case .unknown:
break
unknown case:
break
}
```

-- Ben

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


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

2018-01-03 Thread Dave DeLong via swift-evolution
IMO this is still too large of a hammer for this problem.

This whole “unexpected case” thing is only a problem when you’re linking 
libraries that are external to/shipped independently of your app. Right now, 
the *only* case where this might exist is Swift on the server. We *might* run 
in to this in the future once the ABI stabilizes and we have the Swift 
libraries shipping as part of iOS/macOS/Linux. Other than this, unexpected enum 
cases won’t really be a problem developers have to deal with.

Because this will be such a relatively rare problem, I feel like a syntax 
change like what’s being proposed is a too-massive hammer for such a small nail.

What feels far more appropriate is:

️ Teaching the compiler/checker/whatever about the linking semantics of 
modules. For modules that are packaged inside the final built product, there is 
no need to deal with any unexpected cases, because we already have the 
exhaustiveness check appropriate for that scenario (regardless of whether the 
module is shipped as a binary or compiled from source). The app author decides 
when to update their dependencies, and updating those dependencies will produce 
new warnings/errors as the compiler notices new or deprecated cases. This is 
the current state of things and is completely orthogonal to the entire 
discussion.

and

️ Adding an attribute (@frozen, @tangled, @moana, @whatever) that can be used 
to decorate an enum declaration. This attribute would only need to be consulted 
on enums where the compiler can determine that the module will *not* be part of 
the final built product. (Ie, it’s an “external” module, in my nomenclature). 
This, then, is a module that can update independently of the final app, and 
therefore there are two possible cases:

1️⃣ If the enum is decorated with @frozen, then I, as an app author, 
have the assurance that the enum case will not change in future releases of the 
library, and I can safely switch on all known cases and not have to provide a 
default case. 

2️⃣ If the enum is NOT decorated with @frozen, then I, as an app 
author, have to account for the possibility that the module may update from 
underneath my app, and I have to handle an unknown case. This is simple: the 
compiler should require me to add a “default:” case to my switch statement. 
This warning is produced IFF: the enum is coming from an external module, and 
the enum is not decorated with @frozen.


==

With this proposal, we only have one thing to consider: the spelling of 
@frozen/@moana/@whatever that we decorate enums in external modules with. Other 
than that, the existing behavior we currently have is completely capable of 
covering the possibilities: we just keep using a “default:” case whenever the 
compiler can’t guarantee that we can be exhaustive in our switching.

Where the real work would be is teaching the compiler about 
internally-vs-externally linked modules.

Dave

> On Jan 2, 2018, at 7:07 PM, Jordan Rose via swift-evolution 
>  wrote:
> 
> [Proposal: 
> https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md
>  
> ]
> 
> Whew! Thanks for your feedback, everyone. On the lighter side of 
> feedback—naming things—it seems that most people seem to like '@frozen', and 
> that does in fact have the connotations we want it to have. I like it too.
> 
> More seriously, this discussion has convinced me that it's worth including 
> what the proposal discusses as a 'future' case. The key point that swayed me 
> is that this can produce a warning when the switch is missing a case rather 
> than an error, which both provides the necessary compiler feedback to update 
> your code and allows your dependencies to continue compiling when you update 
> to a newer SDK. I know people on both sides won't be 100% satisfied with 
> this, but does it seem like a reasonable compromise?
> 
> The next question is how to spell it. I'm leaning towards `unexpected case:`, 
> which (a) is backwards-compatible, and (b) also handles "private cases", 
> either the fake kind that you can do in C (as described in the proposal), or 
> some real feature we might add to Swift some day. `unknown case:` isn't bad 
> either.
> 
> I too would like to just do `unknown:` or `unexpected:` but that's 
> technically a source-breaking change:
> 
> switch foo {
> case bar:
>   unknown:
>   while baz() {
> while garply() {
>   if quux() {
> break unknown
>   }
> }
>   }
> }
> 
> Another downside of the `unexpected case:` spelling is that it doesn't work 
> as part of a larger pattern. I don't have a good answer for that one, but 
> perhaps it's acceptable for now.
> 
> I'll write up a revision of the proposal soon and make sure the core team 
> gets my recommendation when they discuss the results of the review.
> 
> ---
> 
> I'll respond to 

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

2018-01-03 Thread Dave DeLong via swift-evolution


> On Jan 2, 2018, at 10:26 PM, Kelvin Ma via swift-evolution 
>  wrote:
> 
> 
> 
> On Tue, Jan 2, 2018 at 11:45 PM, Nevin Brackett-Rozinsky via swift-evolution 
> > wrote:
> On Tue, Jan 2, 2018 at 9:07 PM, Jordan Rose via swift-evolution 
> > wrote:
> [Proposal: 
> https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md
>  
> ]
> 
> Whew! Thanks for your feedback, everyone. On the lighter side of 
> feedback—naming things—it seems that most people seem to like '@frozen', and 
> that does in fact have the connotations we want it to have. I like it too.
> 
> More seriously, this discussion has convinced me that it's worth including 
> what the proposal discusses as a 'future' case. The key point that swayed me 
> is that this can produce a warning when the switch is missing a case rather 
> than an error, which both provides the necessary compiler feedback to update 
> your code and allows your dependencies to continue compiling when you update 
> to a newer SDK. I know people on both sides won't be 100% satisfied with 
> this, but does it seem like a reasonable compromise?
> 
> The next question is how to spell it. I'm leaning towards `unexpected case:`, 
> which (a) is backwards-compatible, and (b) also handles "private cases", 
> either the fake kind that you can do in C (as described in the proposal), or 
> some real feature we might add to Swift some day. `unknown case:` isn't bad 
> either.
> 
> I too would like to just do `unknown:` or `unexpected:` but that's 
> technically a source-breaking change:
> 
> switch foo {
> case bar:
>   unknown:
>   while baz() {
> while garply() {
>   if quux() {
> break unknown
>   }
> }
>   }
> }
> 
> Another downside of the `unexpected case:` spelling is that it doesn't work 
> as part of a larger pattern. I don't have a good answer for that one, but 
> perhaps it's acceptable for now.
> 
> I'll write up a revision of the proposal soon and make sure the core team 
> gets my recommendation when they discuss the results of the review.
> 
> ---
> 
> I'll respond to a few of the more intricate discussions tomorrow, including 
> the syntax of putting a new declaration inside the enum rather than outside. 
> Thank you again, everyone, and happy new year!
> 
> Jordan
> 
> 
> +1 to warning instead of error
> +1 to unknown/unexpected case
> +1 to “@frozen” or any other reasonable spelling, they are all fine by me.
> 
> +1 to “@tangled” because abi is complicated

+1 to “@moana” because these are all just Disney movies

>  
> 
> The one remaining problem to solve is making sure multi-module apps can leave 
> out the unknown/unexpected case on enums from modules which are part of the 
> app itself and thus cannot be updated independently of it. John McCall’s 
> version-locking plan sounds promising, though we should explore the available 
> options before finalizing a course.
> 
> Perhaps we need a concept of submodules, or supermodules, or some other way 
> to demarcate the boundaries of a resilience domain.
> 
> Nevin
> 
> i would support a proper submodule system over some verson-locking system 
> that only the most advanced users will probably know about. i think modules 
> should be one level higher than what they’re currently being used for right 
> now for lack of a better alternative (one application should never have to 
> define more than one capital M Module). submodules shouldn’t be that hard to 
> implement, though the submodule names should be part of ABI to avoid name 
> mangling problems
> 
> ___
> 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


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

2018-01-02 Thread Goffredo Marocchi via swift-evolution


Sent from my iPhone

> On 3 Jan 2018, at 07:42, Goffredo Marocchi  wrote:
> 
> 
>> On 3 Jan 2018, at 02:07, Jordan Rose via swift-evolution 
>>  wrote:
>> 
>> [Proposal: 
>> https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md]
>> 
>> Whew! Thanks for your feedback, everyone. On the lighter side of 
>> feedback—naming things—it seems that most people seem to like '@frozen', and 
>> that does in fact have the connotations we want it to have. I like it too.
>> 
>> More seriously, this discussion has convinced me that it's worth including 
>> what the proposal discusses as a 'future' case. The key point that swayed me 
>> is that this can produce a warning when the switch is missing a case rather 
>> than an error, which both provides the necessary compiler feedback to update 
>> your code and allows your dependencies to continue compiling when you update 
>> to a newer SDK. I know people on both sides won't be 100% satisfied with 
>> this, but does it seem like a reasonable compromise?
> 
> If we can optionally treat this warning as an error yeah, but considering the 
> restricted use case, the default should still be exhaustive with unfrozen the 
> optional keyword that can be applied to opt out of the error.
> 
> Regardless of that, if it is not going to cause runtime issues why should it 
> not be a compile time error and just a warning? I think if you recompile the 
> app and are either targeting a new SDK or updating a library you bundle that 
> you should have to address this issue. Still, better than nothing :).
> 
>> 
>> The next question is how to spell it. I'm leaning towards `unexpected 
>> case:`, which (a) is backwards-compatible, and (b) also handles "private 
>> cases", either the fake kind that you can do in C (as described in the 
>> proposal), or some real feature we might add to Swift some day. `unknown 
>> case:` isn't bad either.
>> 
>> I too would like to just do `unknown:` or `unexpected:` but that's 
>> technically a source-breaking change:
>> 
>> switch foo {
>> case bar:
>>   unknown:
>>   while baz() {
>> while garply() {
>>   if quux() {
>> break unknown
>>   }
>> }
>>   }
>> }
>> 
>> Another downside of the `unexpected case:` spelling is that it doesn't work 
>> as part of a larger pattern. I don't have a good answer for that one, but 
>> perhaps it's acceptable for now.
>> 
>> I'll write up a revision of the proposal soon and make sure the core team 
>> gets my recommendation when they discuss the results of the review.
>> 
>> ---
>> 
>> I'll respond to a few of the more intricate discussions tomorrow, including 
>> the syntax of putting a new declaration inside the enum rather than outside. 
>> Thank you again, everyone, and happy new year!
>> 
>> Jordan
>> 
>> ___
>> 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


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

2018-01-02 Thread Howard Lovatt via swift-evolution
I am not convinced by these arguments, they seem to be a ‘poor man’s’ 
versioning system. For example consider:

// In module. 
public enum E {
case A, B, C
}

// In application. 
switch e {
case A: a()
default: d()
unknown case: u()
}

When e == B or C is u() or d() called? I would expect d() since the application 
programmer obviously intends to handle unexpected differently than default. 

Now when E is modified and case D added by the module programmer I would expect 
B and C to still call d() and D to call u(). 

To achieve the above behaviour the switch encodes that when it compiled default 
was for B and C and therefore D is the new case and therefore it calls u(). 

When the code is recompiled against the new module the behaviour changes. D 
will now call d(). This will be without a warning. Hence I am classing this as 
a ‘poor man’s’ module system. 

Possible solutions include:

  1. You can’t have a default with an extensible enum, but you must have a 
unknown case. This prevents handling default cases at all, you have to list all 
the existing cases separately. 

  2. As described above in 1 the unknown case does very little. Instead just 
use default and don’t introduce unknown. 

  3. Have a versioned module system that requires enum cases and matching 
switch statements to be versioned. EG:

// In module. 
@version(1) public enum E {
case A, B, C
}
@version(1.6) public enum E {
case A, C, D
}

// In application. 
@version(1.5) switch e {
case A: a()
default: d()
unknown case: u()
}

The module system would have to publish which enum cases were available for 
each version including all old versions. Note how the above notation allows 
removal and addition of cases. 

-- Howard. 

> On 3 Jan 2018, at 12:26 am, Kelvin Ma via swift-evolution 
>  wrote:
> 
> 
> 
>> On Tue, Jan 2, 2018 at 11:45 PM, Nevin Brackett-Rozinsky via swift-evolution 
>>  wrote:
>>> On Tue, Jan 2, 2018 at 9:07 PM, Jordan Rose via swift-evolution 
>>>  wrote:
>>> [Proposal: 
>>> https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md]
>>> 
>>> Whew! Thanks for your feedback, everyone. On the lighter side of 
>>> feedback—naming things—it seems that most people seem to like '@frozen', 
>>> and that does in fact have the connotations we want it to have. I like it 
>>> too.
>>> 
>>> More seriously, this discussion has convinced me that it's worth including 
>>> what the proposal discusses as a 'future' case. The key point that swayed 
>>> me is that this can produce a warning when the switch is missing a case 
>>> rather than an error, which both provides the necessary compiler feedback 
>>> to update your code and allows your dependencies to continue compiling when 
>>> you update to a newer SDK. I know people on both sides won't be 100% 
>>> satisfied with this, but does it seem like a reasonable compromise?
>>> 
>>> The next question is how to spell it. I'm leaning towards `unexpected 
>>> case:`, which (a) is backwards-compatible, and (b) also handles "private 
>>> cases", either the fake kind that you can do in C (as described in the 
>>> proposal), or some real feature we might add to Swift some day. `unknown 
>>> case:` isn't bad either.
>>> 
>>> I too would like to just do `unknown:` or `unexpected:` but that's 
>>> technically a source-breaking change:
>>> 
>>> switch foo {
>>> case bar:
>>>   unknown:
>>>   while baz() {
>>> while garply() {
>>>   if quux() {
>>> break unknown
>>>   }
>>> }
>>>   }
>>> }
>>> 
>>> Another downside of the `unexpected case:` spelling is that it doesn't work 
>>> as part of a larger pattern. I don't have a good answer for that one, but 
>>> perhaps it's acceptable for now.
>>> 
>>> I'll write up a revision of the proposal soon and make sure the core team 
>>> gets my recommendation when they discuss the results of the review.
>>> 
>>> ---
>>> 
>>> I'll respond to a few of the more intricate discussions tomorrow, including 
>>> the syntax of putting a new declaration inside the enum rather than 
>>> outside. Thank you again, everyone, and happy new year!
>>> 
>>> Jordan
>> 
>> 
>> +1 to warning instead of error
>> +1 to unknown/unexpected case
>> +1 to “@frozen” or any other reasonable spelling, they are all fine by me.
> 
> +1 to “@tangled” because abi is complicated
>  
>> 
>> The one remaining problem to solve is making sure multi-module apps can 
>> leave out the unknown/unexpected case on enums from modules which are part 
>> of the app itself and thus cannot be updated independently of it. John 
>> McCall’s version-locking plan sounds promising, though we should explore the 
>> available options before finalizing a course.
>> 
>> Perhaps we need a concept of submodules, or supermodules, or some other way 
>> to demarcate the boundaries of a 

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

2018-01-02 Thread Kelvin Ma via swift-evolution
On Tue, Jan 2, 2018 at 11:45 PM, Nevin Brackett-Rozinsky via
swift-evolution  wrote:

> On Tue, Jan 2, 2018 at 9:07 PM, Jordan Rose via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> [Proposal: https://github.com/apple/swift-evolution/blob/mas
>> ter/proposals/0192-non-exhaustive-enums.md]
>>
>> Whew! Thanks for your feedback, everyone. On the lighter side of
>> feedback—naming things—it seems that most people seem to like '*@frozen*',
>> and that does in fact have the connotations we want it to have. I like it
>> too.
>>
>> More seriously, this discussion has convinced me that it's worth
>> including what the proposal discusses as a *'future' case*. The key
>> point that swayed me is that this can produce a *warning* when the
>> switch is missing a case rather than an *error,* which both provides the
>> necessary compiler feedback to update your code and allows your
>> dependencies to continue compiling when you update to a newer SDK. I know
>> people on both sides won't be 100% satisfied with this, but does it seem
>> like a reasonable compromise?
>>
>> The next question is how to spell it. I'm leaning towards `unexpected
>> case:`, which (a) is backwards-compatible, and (b) also handles "private
>> cases", either the fake kind that you can do in C (as described in the
>> proposal), or some real feature we might add to Swift some day. `unknown
>> case:` isn't bad either.
>>
>> I too would like to just do `unknown:` or `unexpected:` but that's
>> technically a source-breaking change:
>>
>> switch foo {
>> case bar:
>>   unknown:
>>   while baz() {
>> while garply() {
>>   if quux() {
>> break unknown
>>   }
>> }
>>   }
>> }
>>
>>
>> Another downside of the `unexpected case:` spelling is that it doesn't
>> work as part of a larger pattern. I don't have a good answer for that one,
>> but perhaps it's acceptable for now.
>>
>> I'll write up a revision of the proposal soon and make sure the core team
>> gets my recommendation when they discuss the results of the review.
>>
>> ---
>>
>> I'll respond to a few of the more intricate discussions tomorrow,
>> including the syntax of putting a new declaration inside the enum rather
>> than outside. Thank you again, everyone, and happy new year!
>>
>> Jordan
>>
>
>
> +1 to warning instead of error
> +1 to unknown/unexpected case
> +1 to “@frozen” or any other reasonable spelling, they are all fine by me.
>

+1 to “@tangled” because abi is complicated


>
> The one remaining problem to solve is making sure multi-module apps can
> leave out the unknown/unexpected case on enums from modules which are part
> of the app itself and thus cannot be updated independently of it. John
> McCall’s version-locking plan sounds promising, though we should explore
> the available options before finalizing a course.
>
> Perhaps we need a concept of submodules, or supermodules, or some other
> way to demarcate the boundaries of a resilience domain.
>
> Nevin
>

i would support a proper submodule system over some verson-locking system
that only the most advanced users will probably know about. i think modules
should be one level higher than what they’re currently being used for right
now for lack of a better alternative (one application should never have to
define more than one capital M Module). submodules shouldn’t be that hard
to implement, though the submodule names should be part of ABI to avoid
name mangling problems
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2018-01-02 Thread Nevin Brackett-Rozinsky via swift-evolution
On Tue, Jan 2, 2018 at 9:07 PM, Jordan Rose via swift-evolution <
swift-evolution@swift.org> wrote:

> [Proposal: https://github.com/apple/swift-evolution/blob/
> master/proposals/0192-non-exhaustive-enums.md]
>
> Whew! Thanks for your feedback, everyone. On the lighter side of
> feedback—naming things—it seems that most people seem to like '*@frozen*',
> and that does in fact have the connotations we want it to have. I like it
> too.
>
> More seriously, this discussion has convinced me that it's worth including
> what the proposal discusses as a *'future' case*. The key point that
> swayed me is that this can produce a *warning* when the switch is missing
> a case rather than an *error,* which both provides the necessary compiler
> feedback to update your code and allows your dependencies to continue
> compiling when you update to a newer SDK. I know people on both sides won't
> be 100% satisfied with this, but does it seem like a reasonable compromise?
>
> The next question is how to spell it. I'm leaning towards `unexpected
> case:`, which (a) is backwards-compatible, and (b) also handles "private
> cases", either the fake kind that you can do in C (as described in the
> proposal), or some real feature we might add to Swift some day. `unknown
> case:` isn't bad either.
>
> I too would like to just do `unknown:` or `unexpected:` but that's
> technically a source-breaking change:
>
> switch foo {
> case bar:
>   unknown:
>   while baz() {
> while garply() {
>   if quux() {
> break unknown
>   }
> }
>   }
> }
>
>
> Another downside of the `unexpected case:` spelling is that it doesn't
> work as part of a larger pattern. I don't have a good answer for that one,
> but perhaps it's acceptable for now.
>
> I'll write up a revision of the proposal soon and make sure the core team
> gets my recommendation when they discuss the results of the review.
>
> ---
>
> I'll respond to a few of the more intricate discussions tomorrow,
> including the syntax of putting a new declaration inside the enum rather
> than outside. Thank you again, everyone, and happy new year!
>
> Jordan
>


+1 to warning instead of error
+1 to unknown/unexpected case
+1 to “@frozen” or any other reasonable spelling, they are all fine by me.

The one remaining problem to solve is making sure multi-module apps can
leave out the unknown/unexpected case on enums from modules which are part
of the app itself and thus cannot be updated independently of it. John
McCall’s version-locking plan sounds promising, though we should explore
the available options before finalizing a course.

Perhaps we need a concept of submodules, or supermodules, or some other way
to demarcate the boundaries of a resilience domain.

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


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

2018-01-02 Thread Xiaodi Wu via swift-evolution
On Tue, Jan 2, 2018 at 8:49 PM, Matthew Johnson 
wrote:

>
> On Jan 2, 2018, at 8:45 PM, Xiaodi Wu via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> On Tue, Jan 2, 2018 at 8:07 PM, Jordan Rose via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> [Proposal: https://github.com/apple/swift-evolution/blob/mas
>> ter/proposals/0192-non-exhaustive-enums.md]
>>
>> Whew! Thanks for your feedback, everyone. On the lighter side of
>> feedback—naming things—it seems that most people seem to like '*@frozen*',
>> and that does in fact have the connotations we want it to have. I like it
>> too.
>>
>> More seriously, this discussion has convinced me that it's worth
>> including what the proposal discusses as a *'future' case*. The key
>> point that swayed me is that this can produce a *warning* when the
>> switch is missing a case rather than an *error,* which both provides the
>> necessary compiler feedback to update your code and allows your
>> dependencies to continue compiling when you update to a newer SDK. I know
>> people on both sides won't be 100% satisfied with this, but does it seem
>> like a reasonable compromise?
>>
>> The next question is how to spell it. I'm leaning towards `unexpected
>> case:`, which (a) is backwards-compatible, and (b) also handles "private
>> cases", either the fake kind that you can do in C (as described in the
>> proposal), or some real feature we might add to Swift some day. `unknown
>> case:` isn't bad either.
>>
>> I too would like to just do `unknown:` or `unexpected:` but that's
>> technically a source-breaking change:
>>
>> switch foo {
>> case bar:
>>   unknown:
>>   while baz() {
>> while garply() {
>>   if quux() {
>> break unknown
>>   }
>> }
>>   }
>> }
>>
>>
>> Another downside of the `unexpected case:` spelling is that it doesn't
>> work as part of a larger pattern. I don't have a good answer for that one,
>> but perhaps it's acceptable for now.
>>
>> I'll write up a revision of the proposal soon and make sure the core team
>> gets my recommendation when they discuss the results of the review.
>>
>> ---
>>
>> I'll respond to a few of the more intricate discussions tomorrow,
>> including the syntax of putting a new declaration inside the enum rather
>> than outside. Thank you again, everyone, and happy new year!
>>
>
> I do like this spelling of `@frozen`, and `unknown case` looks perfectly
> cromulent to me. If this is the path to go down, I'd urge more explicit
> design as to what happens when `unknown case` and `default` are mixed. I
> would imagine the most consistent design would be:
>
> `unknown case` should allow `default` to be omitted if the switch is
> otherwise exhaustive, obviously.
> `default` should allow `unknown case` to be omitted, just like any other
> case may then be omitted.
> `unknown case` before `default` should be allowed, just like any other
> case before `default`; in that case, only known cases not otherwise matched
> reach the `default`.
> `default` before `unknown case` makes the latter unreachable, just like
> any other case after `default`.
>
> The issue here remains that of testability. I wonder if, for such
> purposes, unknown case should be instantiable when testably imported, with
> some grammar. In its simplest and yet most exotic form, we could imagine
> code that testably imports the enum to be allowed to instantiate any
> made-up case whatsoever (e.g., `@testable import Foo.MyEnum; let x = MyEnum.
> asdfasdfasdfNonexistent`).
>
>
> What should happen when an unknown case instantiated via a testability
> mechanism is passed to the library that vended the enum (which is able to
> truly exhaustively switch over the enum)?  I would like to see a solution
> to the testability problem and answering this question seems to be the most
> difficult part of finding a solution.  The best answer is not obvious to me.
>

Indeed, you're quite right. And the whole notion is actually half-baked
because a @testable import should treat the enum as though internal and
therefore exhaustive.

It would appear, however, that testability would require the library itself
to handle unknown cases. That seems annoying but potentially justifiable.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2018-01-02 Thread Matthew Johnson via swift-evolution

> On Jan 2, 2018, at 8:45 PM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> On Tue, Jan 2, 2018 at 8:07 PM, Jordan Rose via swift-evolution 
> > wrote:
> [Proposal: 
> https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md
>  
> ]
> 
> Whew! Thanks for your feedback, everyone. On the lighter side of 
> feedback—naming things—it seems that most people seem to like '@frozen', and 
> that does in fact have the connotations we want it to have. I like it too.
> 
> More seriously, this discussion has convinced me that it's worth including 
> what the proposal discusses as a 'future' case. The key point that swayed me 
> is that this can produce a warning when the switch is missing a case rather 
> than an error, which both provides the necessary compiler feedback to update 
> your code and allows your dependencies to continue compiling when you update 
> to a newer SDK. I know people on both sides won't be 100% satisfied with 
> this, but does it seem like a reasonable compromise?
> 
> The next question is how to spell it. I'm leaning towards `unexpected case:`, 
> which (a) is backwards-compatible, and (b) also handles "private cases", 
> either the fake kind that you can do in C (as described in the proposal), or 
> some real feature we might add to Swift some day. `unknown case:` isn't bad 
> either.
> 
> I too would like to just do `unknown:` or `unexpected:` but that's 
> technically a source-breaking change:
> 
> switch foo {
> case bar:
>   unknown:
>   while baz() {
> while garply() {
>   if quux() {
> break unknown
>   }
> }
>   }
> }
> 
> Another downside of the `unexpected case:` spelling is that it doesn't work 
> as part of a larger pattern. I don't have a good answer for that one, but 
> perhaps it's acceptable for now.
> 
> I'll write up a revision of the proposal soon and make sure the core team 
> gets my recommendation when they discuss the results of the review.
> 
> ---
> 
> I'll respond to a few of the more intricate discussions tomorrow, including 
> the syntax of putting a new declaration inside the enum rather than outside. 
> Thank you again, everyone, and happy new year!
> 
> I do like this spelling of `@frozen`, and `unknown case` looks perfectly 
> cromulent to me. If this is the path to go down, I'd urge more explicit 
> design as to what happens when `unknown case` and `default` are mixed. I 
> would imagine the most consistent design would be:
> 
> `unknown case` should allow `default` to be omitted if the switch is 
> otherwise exhaustive, obviously.
> `default` should allow `unknown case` to be omitted, just like any other case 
> may then be omitted.
> `unknown case` before `default` should be allowed, just like any other case 
> before `default`; in that case, only known cases not otherwise matched reach 
> the `default`.
> `default` before `unknown case` makes the latter unreachable, just like any 
> other case after `default`.
> 
> The issue here remains that of testability. I wonder if, for such purposes, 
> unknown case should be instantiable when testably imported, with some 
> grammar. In its simplest and yet most exotic form, we could imagine code that 
> testably imports the enum to be allowed to instantiate any made-up case 
> whatsoever (e.g., `@testable import Foo.MyEnum; let x = 
> MyEnum.asdfasdfasdfNonexistent`).

What should happen when an unknown case instantiated via a testability 
mechanism is passed to the library that vended the enum (which is able to truly 
exhaustively switch over the enum)?  I would like to see a solution to the 
testability problem and answering this question seems to be the most difficult 
part of finding a solution.  The best answer is not obvious to me.

> 
> 
> ___
> 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


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

2018-01-02 Thread Xiaodi Wu via swift-evolution
On Tue, Jan 2, 2018 at 8:07 PM, Jordan Rose via swift-evolution <
swift-evolution@swift.org> wrote:

> [Proposal: https://github.com/apple/swift-evolution/blob/
> master/proposals/0192-non-exhaustive-enums.md]
>
> Whew! Thanks for your feedback, everyone. On the lighter side of
> feedback—naming things—it seems that most people seem to like '*@frozen*',
> and that does in fact have the connotations we want it to have. I like it
> too.
>
> More seriously, this discussion has convinced me that it's worth including
> what the proposal discusses as a *'future' case*. The key point that
> swayed me is that this can produce a *warning* when the switch is missing
> a case rather than an *error,* which both provides the necessary compiler
> feedback to update your code and allows your dependencies to continue
> compiling when you update to a newer SDK. I know people on both sides won't
> be 100% satisfied with this, but does it seem like a reasonable compromise?
>
> The next question is how to spell it. I'm leaning towards `unexpected
> case:`, which (a) is backwards-compatible, and (b) also handles "private
> cases", either the fake kind that you can do in C (as described in the
> proposal), or some real feature we might add to Swift some day. `unknown
> case:` isn't bad either.
>
> I too would like to just do `unknown:` or `unexpected:` but that's
> technically a source-breaking change:
>
> switch foo {
> case bar:
>   unknown:
>   while baz() {
> while garply() {
>   if quux() {
> break unknown
>   }
> }
>   }
> }
>
>
> Another downside of the `unexpected case:` spelling is that it doesn't
> work as part of a larger pattern. I don't have a good answer for that one,
> but perhaps it's acceptable for now.
>
> I'll write up a revision of the proposal soon and make sure the core team
> gets my recommendation when they discuss the results of the review.
>
> ---
>
> I'll respond to a few of the more intricate discussions tomorrow,
> including the syntax of putting a new declaration inside the enum rather
> than outside. Thank you again, everyone, and happy new year!
>

I do like this spelling of `@frozen`, and `unknown case` looks perfectly
cromulent to me. If this is the path to go down, I'd urge more explicit
design as to what happens when `unknown case` and `default` are mixed. I
would imagine the most consistent design would be:

`unknown case` should allow `default` to be omitted if the switch is
otherwise exhaustive, obviously.
`default` should allow `unknown case` to be omitted, just like any other
case may then be omitted.
`unknown case` before `default` should be allowed, just like any other case
before `default`; in that case, only known cases not otherwise matched
reach the `default`.
`default` before `unknown case` makes the latter unreachable, just like any
other case after `default`.

The issue here remains that of testability. I wonder if, for such purposes,
unknown case should be instantiable when testably imported, with some
grammar. In its simplest and yet most exotic form, we could imagine code
that testably imports the enum to be allowed to instantiate any made-up
case whatsoever (e.g., `@testable import Foo.MyEnum; let x =
MyEnum.asdfasdfasdfNonexistent`).
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2018-01-02 Thread Matthew Johnson via swift-evolution

> On Jan 2, 2018, at 8:07 PM, Jordan Rose via swift-evolution 
>  wrote:
> 
> [Proposal: 
> https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md
>  
> ]
> 
> Whew! Thanks for your feedback, everyone. On the lighter side of 
> feedback—naming things—it seems that most people seem to like '@frozen', and 
> that does in fact have the connotations we want it to have. I like it too.
> 
> More seriously, this discussion has convinced me that it's worth including 
> what the proposal discusses as a 'future' case. The key point that swayed me 
> is that this can produce a warning when the switch is missing a case rather 
> than an error, which both provides the necessary compiler feedback to update 
> your code and allows your dependencies to continue compiling when you update 
> to a newer SDK. I know people on both sides won't be 100% satisfied with 
> this, but does it seem like a reasonable compromise?

I think this strikes a reasonable balance.  It allows people to continue 
compiling a dependency that hasn’t been updated if necessary while knowing (if 
they look at the compilation log) that the unknown case may be executed with 
their current SDK.  It is also straightforward to adopt a “treat warnings as 
errors” policy if desired.  It may also be possible to selectively silence or 
upgrade targeted warnings in the future which would also afford additional 
control over how these warnings are treated.

I spent some time digging through the archives tonight and found one of the 
examples I personally found compelling in motivating the need for this: 
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170904/039512.html
 
.
  It is Brent Royal-Gordon’s discussion of `SKPaymentTransactionState`:

> `SKPaymentTransactionState`, which tells you the status of an in-app purchase 
> transaction, probably would have seemed like a data enum in iOS 3. After all, 
> what states could a transaction take besides `purchasing`, `purchased`, 
> `failed`, or `restored`? But in iOS 8, StoreKit introduced the `deferred` 
> state to handle a new parental-approval feature. Third-party developers did 
> not expect this and had to scramble to handle the unanticipated change.


This is a great example of an Apple-provided enum which is not likely to be 
declared exhaustive but for which people will have legitimate reasons to switch 
over.  I believe there were other good examples discussing 3rd party libraries 
(related to networking?) shared on the list in the past but I was unable to 
find them in the time I had available this evening.

> 
> The next question is how to spell it. I'm leaning towards `unexpected case:`, 
> which (a) is backwards-compatible, and (b) also handles "private cases", 
> either the fake kind that you can do in C (as described in the proposal), or 
> some real feature we might add to Swift some day. `unknown case:` isn't bad 
> either.

I agree with this direction because it also addresses private cases.  It isn’t 
clear to me why `future` wouldn’t be backwards compatible while `unexpected` or 
`unknown` would but that isn’t a deciding factor for me.

I think `unknown` is the best option.  `unexpected` doesn’t seem right as it 
isn’t exactly unexpected.  When we use this keyword it is precisely because we 
know there may be private cases or new cases added in the future.  We are 
expecting to eventually come across a case we didn’t know about when writing 
the code.

> 
> I too would like to just do `unknown:` or `unexpected:` but that's 
> technically a source-breaking change:
> 
> switch foo {
> case bar:
>   unknown:
>   while baz() {
> while garply() {
>   if quux() {
> break unknown
>   }
> }
>   }
> }

The potential for source breakage here seems pretty remote.  I would be 
happiest if we could just accept it but this will be a relatively rarely used 
feature so I won’t complain if a syntactic compromise needs to be made.

> 
> Another downside of the `unexpected case:` spelling is that it doesn't work 
> as part of a larger pattern. I don't have a good answer for that one, but 
> perhaps it's acceptable for now.
> 
> I'll write up a revision of the proposal soon and make sure the core team 
> gets my recommendation when they discuss the results of the review.

Thanks for keeping an open mind about this and listening to everyone’s feedback 
Jordan!  I really appreciate it.

> 
> ---
> 
> I'll respond to a few of the more intricate discussions tomorrow, including 
> the syntax of putting a new declaration inside the enum rather than outside. 
> Thank you again, everyone, and happy new year!

Happy new year to you as well!

> 
> Jordan
> 
> ___
> swift-evolution mailing list
> 

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

2018-01-02 Thread Jordan Rose via swift-evolution
[Proposal: 
https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md
 
]

Whew! Thanks for your feedback, everyone. On the lighter side of 
feedback—naming things—it seems that most people seem to like '@frozen', and 
that does in fact have the connotations we want it to have. I like it too.

More seriously, this discussion has convinced me that it's worth including what 
the proposal discusses as a 'future' case. The key point that swayed me is that 
this can produce a warning when the switch is missing a case rather than an 
error, which both provides the necessary compiler feedback to update your code 
and allows your dependencies to continue compiling when you update to a newer 
SDK. I know people on both sides won't be 100% satisfied with this, but does it 
seem like a reasonable compromise?

The next question is how to spell it. I'm leaning towards `unexpected case:`, 
which (a) is backwards-compatible, and (b) also handles "private cases", either 
the fake kind that you can do in C (as described in the proposal), or some real 
feature we might add to Swift some day. `unknown case:` isn't bad either.

I too would like to just do `unknown:` or `unexpected:` but that's technically 
a source-breaking change:

switch foo {
case bar:
  unknown:
  while baz() {
while garply() {
  if quux() {
break unknown
  }
}
  }
}

Another downside of the `unexpected case:` spelling is that it doesn't work as 
part of a larger pattern. I don't have a good answer for that one, but perhaps 
it's acceptable for now.

I'll write up a revision of the proposal soon and make sure the core team gets 
my recommendation when they discuss the results of the review.

---

I'll respond to a few of the more intricate discussions tomorrow, including the 
syntax of putting a new declaration inside the enum rather than outside. Thank 
you again, everyone, and happy new year!

Jordan

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


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

2018-01-02 Thread Drew Crawford via swift-evolution
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 (kreme...@apple.com) 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, 

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

2017-12-21 Thread Stephen Celis via swift-evolution
-1

It took awhile to catch up. I understand the motivation but don't agree with 
the solution. The suggested proposal adds language complexity that can 
hopefully be solved in other ways.

In catching up I related to Howard Lovatt's response. Jordan responded:

> On Dec 20, 2017, at 2:33 PM, Jordan Rose via swift-evolution 
>  wrote:
> 
> I find it interesting that you call this the "unsafe" case. From my point of 
> view , it is very much in line with Swift's 
> current design to have the default be "force clients to consider all 
> possibilities" (like Optional), as well as "let library authors decide what a 
> client should be able to rely on" (like 'open').

I don't understand this. Optional is exhaustive. What you're describing is more 
like Swift error handling, which is quite different and much more cumbersome in 
use.

> This is an interesting point that I probably should have expanded more in the 
> "comparison with other languages" section. Swift has protocols too, and you 
> can build most of the features of enums with protocols. (Set aside the 
> inferior pattern-matching for now; that's something we could add to Swift.) 
> This is currently much more heavyweight than enums, but let's roll with it.
> 
> Next we have to deal with C enums, which can have "private cases" or 
> newly-added cases. Okay, maybe those get imported as structs instead, like 
> NS_OPTIONS. That's not too bad, is it?
> 
> Now we're back in a place where 'enum' always means "exhaustive". That's 
> good, right? Except…now we have a kind of type where the recommendation will 
> be "don't use these in your library's public API; they'll be stuck that way 
> forever", a trap waiting for library authors. That's a problem C has with 
> structs, and it's something we don't want to bring into Swift. Making a 
> library necessarily requires more care than making an app, but we don't want 
> there to be techniques that only make sense within a module, and are 
> discouraged when writing a library.
> 
> So we can implement this world in Swift. I just don't think it'll be a better 
> one. When someone makes a library, the default should be safe for them. That 
> means that they reserve the ability to add cases, and also to make the enum 
> "exhaustive" in the future if it turns out that's the right thing to do.
> 
> (You're free to continue to disagree with me on this; thanks for getting me 
> to write it out.)


I don't think the default third-party library case mirrors Foundation and UIKit 
(and authors that provide libraries like that must take more care in general 
and don't require extra language sugar that benefits just them). There are 
plenty of library authors whose default case is: when you upgrade to use our 
latest version, you need to consider all added cases, as it's source-breaking. 
I think this is far more common than the well-kempt releases Apple shepherds 
through each year.

I don't think we should lose our primitive type that always requires exhaustive 
switching, and I don't see the need to overcomplicate the language when we 
already have at-hand solutions (like extensible structs). If we're worried 
about library authors falling into the trap of misusing enums, we should 
provide a better mechanism for declaring raw-representable (or similar) 
entities, via something like NS_RAW_REPRESENTABLE, compiler magic, and/or a 
hygienic macro system.

I'd also like to point out that the current state of Swift development requires 
frameworks separate from the app:

1. If you want to import code into a playground. Playgrounds are a celebrated 
form of code demonstration, but app executable code cannot run in a playground. 
It needs to be extracted to a framework first.

2. SPM executables cannot run tests or have test targets. Testable SPM code 
needs to be extracted to a framework. If you want to test your code, it needs 
to be in a framework.

Both cases above affect app developers that aren't necessarily in the library 
biz. It's not great if the default for them is enums that suddenly become 
non-exhaustive.

Stephen

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


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

2017-12-21 Thread Pitiphong Phongpattranont via swift-evolution
Hello I would like to give a feedback on this SE,

In the proposal, it stats that
In the initial discussion, multiple people were unhappy with the loss of 
compiler warnings for switches over non-exhaustive enums that comes with using 
default—they wanted to be able to handle all cases that exist today, and have 
the compiler tell them when new ones were added. Ultimately I decided not to 
include this in the proposal with the expectation is that switches over 
non-exhaustive enums should be uncommon.

This may not be true for every Swift based app. My scenario is that we are a 
service company who have a open source library for our customer to integrate 
our service into their app. However we also have an official application which 
also uses these libraries too. And since we adopted Swift features as much as 
possible, we do have a lot of public enum types in our libraries and use them 
in our app heavily. This PR will make our code base harder to maintain since we 
lost the complier warning for switches over non-exhaustive enums

I understand that most of the Swift based apps may not suffer from this heavily 
like us but when they do, it’s really a huge pain to maintain this.

Best regards,
Pitiphong P.



> On 20 Dec BE 2560, at 05:58, Ted Kremenek  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
> swift-evolution-annou...@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution-announce

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


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

2017-12-21 Thread Natchanon Luangsomboon via swift-evolution
Oops, I meant to post this on a separate thread. Sorry.

Sincerely,
Natchanon
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-12-21 Thread Natchanon Luangsomboon via swift-evolution
Before answering above, I would like to add
Since the users of the library will likely not accommodate the new cases (as it 
doesn’t exist yet), the `default/future` case will then not provide any real 
usage other than throwing exceptions. So the user will still need to update the 
code to actually accommodate these cases. This proposal doesn’t solve any real 
problem (more than what Swift 4 is currently doing).
Non-exhaustive behavior already exist as the `default` case, which user can 
op-in. So the decision on whether or not the enum is `exhaustive` is currently 
users’. This proposal will shift this decision to the author of the library, 
not the user. This is a huge minus since it moved the responsibility to one 
individual (or a single group of individual) rather than the actual users, and 
also reduce configurability (the user will have little say in whether or not an 
enum is exhaustive).
>From my own experience, most of the time I use `switch`, I intentionally omit 
>`default`, so the when the library update, I do know which portion needs to 
>handle new cases (among other things). If any enum is decided by the author to 
>be non-exhaustive, it would take away this ability. This refers back to 
>previous bullet point.
What is your evaluation of the proposal?
This is a -1.
The ABI resilience can be a plus, but the requiring change in behavior is a 
huge minus, esp. the effect on users’ side of the library. 
Is the problem being addressed significant enough to warrant a change to Swift?
I do see where this problem may arise, but the solution has too much drawback 
to be included in Swift.
Does this proposal fit well with the feel and direction of Swift?
This doesn’t fit well with the feel and direction of the Swift.
As mentioned above, the proposal shift decision on whether or not to support 
(or to require support) future cases to the author of library, not the users. 
IMO, it is not very Swifty (or even a good idea).
If you have used other languages or libraries with a similar feature, how do 
you feel that this proposal compares to those?
I used languages with non-exhaustive enum before, I can never go back after 
using the exhaustive one.
How much effort did you put into your review? A glance, a quick reading, or an 
in-depth study?
A several read through the proposal. I really try to like this proposal, as I 
see that the problem exists, but the solution still doesn’t sound.

Sincerely,
Natchanon

> On Tue, Dec 19, 2017 at 11:58 PM, Ted Kremenek  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
> swift-evolution-annou...@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution-announce
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-12-21 Thread Chris Eidhof via swift-evolution
I can see why this is useful, and understand the problem. However, it does
feel like the wrong solution to a real problem. This seems to be very
similar to the *expression problem*:

> The expression problem is a new name for an old problem.[2][3] The goal
is to define a datatype by cases, where one can add new cases to the
datatype and new functions over the datatype, without recompiling existing
code, and while retaining static type safety (e.g., no casts).
>
> (source: https://en.wikipedia.org/wiki/Expression_problem)

The price we'll pay for this proposal is to always have a default case with
non-exhaustive enums. To me, this feels very similar to the default case in
Swift's error handling, and in that sense it matches the existing language
behavior. However, I find the default case in Swift's error handling quite
annoying (especially if you can guarantee you've handled all possible
errors).

In the case of enums, I'd much rather get a compiler error because I didn't
handle case, than a runtime error because my default caught a case I
actually wanted to catch. Having non-exhaustive enums makes it much harder
to refactor code that uses those enums (if I add a case, the compiler
doesn't give me a list of all the sites I need to fix).

A -1 from me.

I would like a solution to the problem, but I feel that the proposed
solution has too many drawbacks.


On Tue, Dec 19, 2017 at 11:58 PM, Ted Kremenek  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
> swift-evolution-annou...@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution-announce
>
>


-- 
Chris Eidhof
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-12-20 Thread Goffredo Marocchi via swift-evolution

> I am part of the people mentioned in "Preserve exhaustiveness diagnostics for 
> non-exhaustive enums" : I see the completeness check as a major feature of 
> enums, that makes a difference between it and a list of constants in multiple 
> cases.
> So much that in the coding rules of the company I work for, the use of 
> default case requires some specific justification at review time.

Standing ovation :), one of my most loved warnings in -Weverything was ensuring 
switches were exhaustive. 

I quite disagree with being unnecessarily strict with making classes closed by 
default and è una non exhaustive by default and potentially tons of unchecked 
changes ended up in the default case with the “hey, we can force it to be 
exhaustive in the unit tests”. I particularly dislike that line of reasoning in 
a language about strong static typing as “well, write unit tests to get your 
correctness and safety tests” is the JavaScript mantra (of those that see 
TypeScript as pure evil).


> I have a positive opinion on this evolution if it comes with a solution to 
> preserve exhaustiveness diagnostics. Otherwise, I think it lowers the ease of 
> maintenance of code using external libraries.
> 
> One of the risk I fear is that libraries builders might just forget to add 
> the @exhaustive keyword. So it might end up being a pretty common case to 
> have to specify "I want this switch to be exhaustive", just to not loose on 
> maintainability. This could lead to a situation similar to the "fileprivate", 
> that ended up being used much more than expected.
> 
> It is not exactly in the scope of that review, but in the two solution for 
> enforcing exhaustiveness drafted in that proposal, I would rather avoid the 
> second one (the switch!). It would contradict the fact that as of today, the 
> use of the exclamation mark in swift is a pretty clear sign that you are 
> disabling some compiler-provided security at your own risk, and that it might 
> lead to runtime crash (force unwrap, force cast, ...).
> Here, requesting a switch to be exhaustive is adding one more compiler check. 
> It cannot lead to a runtime crash.
> I will be happy to discuss it further in a future review.
> 
> Jerome
> ___
> 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


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

2017-12-20 Thread Jordan Rose via swift-evolution


> On Dec 19, 2017, at 20:15, Howard Lovatt via swift-evolution 
>  wrote:
> 
> As an aside: there seems to be increasingly comments about proposals that say:
> 
>   1. This was discussed at the evaluation stage and rejected. 
>   2. This is how it is implemented in the patch.
> 
> And other comments along those lines. Neither the pre-proposal discussions 
> nor the proposed implementation are intended to limit the scope of the 
> review. Therefore I don’t think people should raise this as reasons. You 
> should remember that the process is deliberately staged this way and 
> different people may well be commenting (in fact the process rather assumes 
> that people in the formal review will be a wider set of people). 
> 
> Anyway gripe over. 
> 
> Proposal link: 
> https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md
>  
> 
> What is your evaluation of the proposal ?
> 
> +1/2
> 
> I only give this a half because whilst it is important I can see three issues:
> 
>   1. It doesn’t seem very Swift like to have a different rule, default 
> non-exhaustive, for public as opposed to non-public. 
> 
I guess people are still misunderstanding this. Within a module, switches must 
still be exhaustive, always, because the switch can never get out of sync with 
the enum definition. The "exhaustive" annotation only applies to clients across 
module boundaries.


>   2. It doesn’t seem very Swift like to have the default the unsafe case. 
> 
I find it interesting that you call this the "unsafe" case. From my point of 
view , it is very much in line with Swift's current 
design to have the default be "force clients to consider all possibilities" 
(like Optional), as well as "let library authors decide what a client should be 
able to rely on" (like 'open').


>   3. Other languages have better solutions - see below under other languages
> 
> Is the problem being addressed significant enough to warrant a change to 
> Swift?
> 
> Yes, Swift ABI compatibility going forwards is important
> 
> Does this proposal fit well with the feel and direction of Swift?
> 
> No. As mentioned above different rules for public and a non-safe default 
> don’t see that Swift like. 
> 
> If you have used other languages or libraries with a similar feature, how do 
> you feel that this proposal compares to those?
> 
> Both Java and Scala have a better solution. In these languages enums (Scala 
> calls them case classes) can implement protocols and the user of an enum 
> rarely writes a switch statement, instead they call protocol methods. Enums 
> in these languages are a fixed set of derived classes; i.e. normal OO 
> programming rather than functional programming, which works well in the case 
> of wanting to expand later the number of enum cases. 
> 
This is an interesting point that I probably should have expanded more in the 
"comparison with other languages" section. Swift has protocols too, and you can 
build most of the features of enums with protocols. (Set aside the inferior 
pattern-matching for now; that's something we could add to Swift.) This is 
currently much more heavyweight than enums, but let's roll with it.

Next we have to deal with C enums, which can have "private cases" or 
newly-added cases. Okay, maybe those get imported as structs instead, like 
NS_OPTIONS. That's not too bad, is it?

Now we're back in a place where 'enum' always means "exhaustive". That's good, 
right? Except…now we have a kind of type where the recommendation will be 
"don't use these in your library's public API; they'll be stuck that way 
forever", a trap waiting for library authors. That's a problem C has with 
structs, and it's something we don't want to bring into Swift. Making a library 
necessarily requires more care than making an app, but we don't want there to 
be techniques that only make sense within a module, and are discouraged when 
writing a library.

So we can implement this world in Swift. I just don't think it'll be a better 
one. When someone makes a library, the default should be safe for them. That 
means that they reserve the ability to add cases, and also to make the enum 
"exhaustive" in the future if it turns out that's the right thing to do.

(You're free to continue to disagree with me on this; thanks for getting me to 
write it out.)

Jordan


> How much effort did you put into your review? A glance, a quick reading, or 
> an in-depth study?
> 
> Have followed the discussions. Used enums in Swift and other languages 
> extensively. 
> 
> -- Howard.
> 
> On 19 Dec 2017, at 12:58 pm, Ted Kremenek  > wrote:
> 
>> When replying, please try to keep the proposal link at the top of the 
>> message:
>> 
>> Proposal link: 
>> 

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

2017-12-20 Thread Jordan Rose via swift-evolution
Thanks for your feedback! I think you're missing the "libraries in the OS" 
aspect of this: if there are Swift libraries in iOS, and Apple ships a software 
update, some enums will get new cases. That means you can always end up in a 
default case if you were switching over those enums, and that's why 'switch!' 
has a '!' in it.

I sympathize with the "exhaustiveness diagnostics must be preserved" idea, but 
it simply doesn't account for package-based development. If libraries are 
allowed to add new cases without breaking source stability, they must not 
introduce new errors into clients. An app author cares about that because they 
want to use the latest Apple SDKs right away, even before any of their 
third-party library dependencies have released an update.

I do actually expect a number of third-party libraries to both mark their enums 
as exhaustive and add new cases in major releases (the ones that are allowed to 
be source-breaking). It's also a source-compatible change to mark a public enum 
as "exhaustive" that wasn't before, so I also expect an early flurry of bug 
reports when people realize this is important in Swift 5. But I think people 
will get the hang of it.

To be clear, I'm open to ideas in this space. It's just that both of the ideas 
in "Alternatives Considered" feel incomplete to me, and unfortunately we do 
have to do something in the near term for both imported enums and for Apple 
APIs (the overlays).

Jordan


> On Dec 20, 2017, at 01:44, Jérôme Duquennoy via swift-evolution 
>  wrote:
> 
> Hi guys,
> 
> I am part of the people mentioned in "Preserve exhaustiveness diagnostics for 
> non-exhaustive enums" : I see the completeness check as a major feature of 
> enums, that makes a difference between it and a list of constants in multiple 
> cases.
> So much that in the coding rules of the company I work for, the use of 
> default case requires some specific justification at review time.
> 
> I have a positive opinion on this evolution if it comes with a solution to 
> preserve exhaustiveness diagnostics. Otherwise, I think it lowers the ease of 
> maintenance of code using external libraries.
> 
> One of the risk I fear is that libraries builders might just forget to add 
> the @exhaustive keyword. So it might end up being a pretty common case to 
> have to specify "I want this switch to be exhaustive", just to not loose on 
> maintainability. This could lead to a situation similar to the "fileprivate", 
> that ended up being used much more than expected.
> 
> It is not exactly in the scope of that review, but in the two solution for 
> enforcing exhaustiveness drafted in that proposal, I would rather avoid the 
> second one (the switch!). It would contradict the fact that as of today, the 
> use of the exclamation mark in swift is a pretty clear sign that you are 
> disabling some compiler-provided security at your own risk, and that it might 
> lead to runtime crash (force unwrap, force cast, ...).
> Here, requesting a switch to be exhaustive is adding one more compiler check. 
> It cannot lead to a runtime crash.
> I will be happy to discuss it further in a future review.
> 
> Jerome
> ___
> 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


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

2017-12-20 Thread Sebastian Hagedorn via swift-evolution
Thanks for your thoughts.

I think 3) is indeed a very common case, but also not affected by this proposal 
or the general issue at all. Unless I’m missing something, I think it makes 
sense to limit the discussion to those enums that are typically switched over 
in client code.

I don’t think 1) outnumbers 2), which is exactly why I think it is important to 
have some sort of exhaustive-checking for 2). If 2) was an edge cases, I 
wouldn’t mind, because 1) behaves the same way with or without the 
implementation of this proposal.

What I was trying to say is: 99% of the times I switch over an enum, I do want 
to consider all available cases in my code, which also means I want to be 
informed (by a warning) if I’m missing something. Without anything like 
`future`, I’ll end up with switches that used to be exhaustive, but are not 
anymore when the library author adds a case, and I don’t learn about it until I 
hit such a case at runtime (documentation aside), which may rarely happen. I’m 
aware that there may be a period of time during which I haven’t updated my code 
and my code has to deal with unexpected cases, but as soon as I get to compile 
my code with the current SDK, I’d like to learn about new cases.


> On 20. Dec 2017, at 11:39, Brent Royal-Gordon  wrote:
> 
>> On Dec 20, 2017, at 1:00 AM, Sebastian Hagedorn via swift-evolution 
>> > 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
> Architechies
> 


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

2017-12-20 Thread Brent Royal-Gordon via swift-evolution
> On Dec 20, 2017, at 1:00 AM, Sebastian Hagedorn via swift-evolution 
>  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
Architechies

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


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

2017-12-20 Thread Jérôme Duquennoy via swift-evolution
Hi guys,

I am part of the people mentioned in "Preserve exhaustiveness diagnostics for 
non-exhaustive enums" : I see the completeness check as a major feature of 
enums, that makes a difference between it and a list of constants in multiple 
cases.
So much that in the coding rules of the company I work for, the use of default 
case requires some specific justification at review time.

I have a positive opinion on this evolution if it comes with a solution to 
preserve exhaustiveness diagnostics. Otherwise, I think it lowers the ease of 
maintenance of code using external libraries.

One of the risk I fear is that libraries builders might just forget to add the 
@exhaustive keyword. So it might end up being a pretty common case to have to 
specify "I want this switch to be exhaustive", just to not loose on 
maintainability. This could lead to a situation similar to the "fileprivate", 
that ended up being used much more than expected.

It is not exactly in the scope of that review, but in the two solution for 
enforcing exhaustiveness drafted in that proposal, I would rather avoid the 
second one (the switch!). It would contradict the fact that as of today, the 
use of the exclamation mark in swift is a pretty clear sign that you are 
disabling some compiler-provided security at your own risk, and that it might 
lead to runtime crash (force unwrap, force cast, ...).
Here, requesting a switch to be exhaustive is adding one more compiler check. 
It cannot lead to a runtime crash.
I will be happy to discuss it further in a future review.

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


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

2017-12-20 Thread Sebastian Hagedorn via swift-evolution
> What is your evaluation of the proposal?
> 
+1 if a `future` case (or similar solution… “unknown” might be a nice keyword, 
although some enums probably have an `.unknown` case which could be confusing) 
is added.
> Is the problem being addressed significant enough to warrant a change to 
> Swift?
> 
I guess so – I understand this is a real issue for binary libraries (so 
basically, Apple).

I don’t think it’s an issue for open source libraries. Forcing the clients to 
update their code when they update the library (which they can do when they 
choose to, usually) seems reasonable to me, compared to the risk of not 
handling the new cases.
> Does this proposal fit well with the feel and direction of Swift?
> 
I don’t mind the default and I believe it’s ok to leave it to the library 
author to decide whether or not an enum should be exhaustive.

That said, I don’t think “you need to add a default case” feels very Swifty. It 
forces you to write code that you essentially have no idea about, so I would 
assume I’d just always put in an assert so I notice it in debug/beta builds, 
and keep my fingers crossed ignoring the unknown case doesn’t do any harm in 
release builds.

I strongly disagree with this:

>  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.

Re: the future case: I don’t expect to actually put any code in there. If it’s 
code I intend to run in any case, it will typically be outside of the switch 
statement. Since the semantic of the new case is unknown to me, what code 
should I write to handle it? For that reason, I don’t think testability is a 
real issue here. I believe the limitation for single-value matching is fine for 
now, and could probably be extended to something like `case (true, future)`.
> If you have used other languages or libraries with a similar feature, how do 
> you feel that this proposal compares to those?
> 
No.
> How much effort did you put into your review? A glance, a quick reading, or 
> an in-depth study?
> 
Carefully read the proposal and followed some of the previous discussions.


> On 19. Dec 2017, at 23:58, Ted Kremenek  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
> swift-evolution-annou...@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution-announce

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


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

2017-12-19 Thread Xiaodi Wu via swift-evolution
On Wed, Dec 20, 2017 at 12:42 AM, Howard Lovatt 
wrote:

> Let me give an example. The recent discussion about filterMap aired in the
> discussion stage misgivings about the name; but it went to review with the
> name filterMap. At the review stage more misgivings were raised, the review
> was returned for amendment. An amended name of compactMap was put forward
> and this was accepted yesterday as a result of the 2nd review. I think that
> this shows how the process can work well. If the discussions were shut down
> with “already covered on Swift Evolution”, then the result wouldn’t be as
> good.
>
> If an argument has been put forward on Evolution, is in the alternatives
> section, and people are still raising the point; it is probably safe to
> assume that the argument hasn’t carried the day and should be revisited.
>

The name of `filterMap` was reviewed a second time because, if I recall,
the core team felt that there might be _additional_ ideas not yet surveyed
the first time. By contrast, if an argument has already been discussed and
is even incorporated into the text of the proposal, then I very strongly
disagree that raising the point again is to be encouraged. It's a different
matter if you have additional _evidence_ or alternative _reasoning_ to
support an argument.

On 19 Dec 2017, at 6:44 pm, Xiaodi Wu  wrote:
>
> On Tue, Dec 19, 2017 at 11:15 PM, Howard Lovatt via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> As an aside: there seems to be increasingly comments about proposals that
>> say:
>>
>>   1. This was discussed at the evaluation stage and rejected.
>>   2. This is how it is implemented in the patch.
>>
>> And other comments along those lines. Neither the pre-proposal
>> discussions nor the proposed implementation are intended to limit the scope
>> of the review. Therefore I don’t think people should raise this as reasons.
>> You should remember that the process is deliberately staged this way and
>> different people may well be commenting (in fact the process rather assumes
>> that people in the formal review will be a wider set of people).
>>
>>
> No, previous discussion don't limit the scope of review per se, but it's
> not helpful to rehash the same arguments again. We want to encourage
> everyone to contribute their most thought-out comments as early in the
> process as possible to give those who propose ideas the fullest chance to
> flesh out any revisions. However, everyone has finite time to contribute,
> and if the same discussions are merely replayed at every stage of review,
> then the process actively discourages thoughtful early participation. After
> all, why bother defending ideas at the pre-proposal stage if I'm going to
> have to spend the time repeating myself in a few months' time anyway?
>
> Of course, if a wider set of people have _new_ comments, those are welcome
> at a later stage. But, there seems to be a sense that if _I_ haven't said
> something already, then _I_ should say it whether or not the same viewpoint
> has already been aired. In my view, such an approach should be actively
> discouraged for the reasons above. Although a strong consensus within the
> community should certainly be accounted for, this list--even at the formal
> review stage--doesn't even come close to approximating the community of
> Swift users at large. Thus, review is not a vote-counting exercise to
> maximize the number of people who chime in, but rather it is meant to
> maximize the number of ideas and perspectives that are aired. If it's
> already been said, it doesn't need to be said again, even if _I_ haven't
> said it myself.
>
>
>> Anyway gripe over.
>>
>> Proposal link: https://github.com/apple/swift-evolution/blob/master/
>> proposals/0192-non-exhaustive-enums.md
>>
>>
>>-
>>
>>What is your evaluation of the proposal?
>>
>>+1/2
>>
>>I only give this a half because whilst it is important I can see
>>three issues:
>>
>>  1. It doesn’t seem very Swift like to have a different rule,
>>default non-exhaustive, for public as opposed to non-public.
>>
>>  2. It doesn’t seem very Swift like to have the default the unsafe
>>case.
>>
>>  3. Other languages have better solutions - see below under other
>>languages
>>-
>>
>>Is the problem being addressed significant enough to warrant a change
>>to Swift?
>>
>>Yes, Swift ABI compatibility going forwards is important
>>-
>>
>>Does this proposal fit well with the feel and direction of Swift?
>>
>>No. As mentioned above different rules for public and a non-safe
>>default don’t see that Swift like.
>>-
>>
>>If you have used other languages or libraries with a similar feature,
>>how do you feel that this proposal compares to those?
>>
>>Both Java and Scala have a better solution. In these languages enums
>>(Scala calls them case classes) can implement protocols and the user of an
>>enum 

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

2017-12-19 Thread Howard Lovatt via swift-evolution
Let me give an example. The recent discussion about filterMap aired in the 
discussion stage misgivings about the name; but it went to review with the name 
filterMap. At the review stage more misgivings were raised, the review was 
returned for amendment. An amended name of compactMap was put forward and this 
was accepted yesterday as a result of the 2nd review. I think that this shows 
how the process can work well. If the discussions were shut down with “already 
covered on Swift Evolution”, then the result wouldn’t be as good.

If an argument has been put forward on Evolution, is in the alternatives 
section, and people are still raising the point; it is probably safe to assume 
that the argument hasn’t carried the day and should be revisited.

-- Howard.

> On 19 Dec 2017, at 6:44 pm, Xiaodi Wu  wrote:
> 
>> On Tue, Dec 19, 2017 at 11:15 PM, Howard Lovatt via swift-evolution 
>>  wrote:
>> As an aside: there seems to be increasingly comments about proposals that 
>> say:
>> 
>>   1. This was discussed at the evaluation stage and rejected. 
>>   2. This is how it is implemented in the patch.
>> 
>> And other comments along those lines. Neither the pre-proposal discussions 
>> nor the proposed implementation are intended to limit the scope of the 
>> review. Therefore I don’t think people should raise this as reasons. You 
>> should remember that the process is deliberately staged this way and 
>> different people may well be commenting (in fact the process rather assumes 
>> that people in the formal review will be a wider set of people).
> 
> No, previous discussion don't limit the scope of review per se, but it's not 
> helpful to rehash the same arguments again. We want to encourage everyone to 
> contribute their most thought-out comments as early in the process as 
> possible to give those who propose ideas the fullest chance to flesh out any 
> revisions. However, everyone has finite time to contribute, and if the same 
> discussions are merely replayed at every stage of review, then the process 
> actively discourages thoughtful early participation. After all, why bother 
> defending ideas at the pre-proposal stage if I'm going to have to spend the 
> time repeating myself in a few months' time anyway?
> 
> Of course, if a wider set of people have _new_ comments, those are welcome at 
> a later stage. But, there seems to be a sense that if _I_ haven't said 
> something already, then _I_ should say it whether or not the same viewpoint 
> has already been aired. In my view, such an approach should be actively 
> discouraged for the reasons above. Although a strong consensus within the 
> community should certainly be accounted for, this list--even at the formal 
> review stage--doesn't even come close to approximating the community of Swift 
> users at large. Thus, review is not a vote-counting exercise to maximize the 
> number of people who chime in, but rather it is meant to maximize the number 
> of ideas and perspectives that are aired. If it's already been said, it 
> doesn't need to be said again, even if _I_ haven't said it myself.
> 
>> 
>> Anyway gripe over. 
>> 
>> Proposal link: 
>> https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md
>> What is your evaluation of the proposal?
>> 
>> +1/2
>> 
>> I only give this a half because whilst it is important I can see three 
>> issues:
>> 
>>   1. It doesn’t seem very Swift like to have a different rule, default 
>> non-exhaustive, for public as opposed to non-public. 
>> 
>>   2. It doesn’t seem very Swift like to have the default the unsafe case. 
>> 
>>   3. Other languages have better solutions - see below under other languages
>> 
>> Is the problem being addressed significant enough to warrant a change to 
>> Swift?
>> 
>> Yes, Swift ABI compatibility going forwards is important
>> 
>> Does this proposal fit well with the feel and direction of Swift?
>> 
>> No. As mentioned above different rules for public and a non-safe default 
>> don’t see that Swift like. 
>> 
>> If you have used other languages or libraries with a similar feature, how do 
>> you feel that this proposal compares to those?
>> 
>> Both Java and Scala have a better solution. In these languages enums (Scala 
>> calls them case classes) can implement protocols and the user of an enum 
>> rarely writes a switch statement, instead they call protocol methods. Enums 
>> in these languages are a fixed set of derived classes; i.e. normal OO 
>> programming rather than functional programming, which works well in the case 
>> of wanting to expand later the number of enum cases. 
>> 
>> How much effort did you put into your review? A glance, a quick reading, or 
>> an in-depth study?
>> 
>> Have followed the discussions. Used enums in Swift and other languages 
>> extensively. 
>> 
>> -- Howard.
>> 
>>> On 19 Dec 2017, at 12:58 pm, Ted Kremenek  wrote:
>>> 
>>> When 

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

2017-12-19 Thread Xiaodi Wu via swift-evolution
On Tue, Dec 19, 2017 at 11:15 PM, Howard Lovatt via swift-evolution <
swift-evolution@swift.org> wrote:

> As an aside: there seems to be increasingly comments about proposals that
> say:
>
>   1. This was discussed at the evaluation stage and rejected.
>   2. This is how it is implemented in the patch.
>
> And other comments along those lines. Neither the pre-proposal discussions
> nor the proposed implementation are intended to limit the scope of the
> review. Therefore I don’t think people should raise this as reasons. You
> should remember that the process is deliberately staged this way and
> different people may well be commenting (in fact the process rather assumes
> that people in the formal review will be a wider set of people).
>
>
No, previous discussion don't limit the scope of review per se, but it's
not helpful to rehash the same arguments again. We want to encourage
everyone to contribute their most thought-out comments as early in the
process as possible to give those who propose ideas the fullest chance to
flesh out any revisions. However, everyone has finite time to contribute,
and if the same discussions are merely replayed at every stage of review,
then the process actively discourages thoughtful early participation. After
all, why bother defending ideas at the pre-proposal stage if I'm going to
have to spend the time repeating myself in a few months' time anyway?

Of course, if a wider set of people have _new_ comments, those are welcome
at a later stage. But, there seems to be a sense that if _I_ haven't said
something already, then _I_ should say it whether or not the same viewpoint
has already been aired. In my view, such an approach should be actively
discouraged for the reasons above. Although a strong consensus within the
community should certainly be accounted for, this list--even at the formal
review stage--doesn't even come close to approximating the community of
Swift users at large. Thus, review is not a vote-counting exercise to
maximize the number of people who chime in, but rather it is meant to
maximize the number of ideas and perspectives that are aired. If it's
already been said, it doesn't need to be said again, even if _I_ haven't
said it myself.


> Anyway gripe over.
>
> Proposal link: https://github.com/apple/swift-evolution/blob/
> master/proposals/0192-non-exhaustive-enums.md
>
>
>-
>
>What is your evaluation of the proposal?
>
>+1/2
>
>I only give this a half because whilst it is important I can see three
>issues:
>
>  1. It doesn’t seem very Swift like to have a different rule, default
>non-exhaustive, for public as opposed to non-public.
>
>  2. It doesn’t seem very Swift like to have the default the unsafe
>case.
>
>  3. Other languages have better solutions - see below under other
>languages
>-
>
>Is the problem being addressed significant enough to warrant a change
>to Swift?
>
>Yes, Swift ABI compatibility going forwards is important
>-
>
>Does this proposal fit well with the feel and direction of Swift?
>
>No. As mentioned above different rules for public and a non-safe
>default don’t see that Swift like.
>-
>
>If you have used other languages or libraries with a similar feature,
>how do you feel that this proposal compares to those?
>
>Both Java and Scala have a better solution. In these languages enums
>(Scala calls them case classes) can implement protocols and the user of an
>enum rarely writes a switch statement, instead they call protocol methods.
>Enums in these languages are a fixed set of derived classes; i.e. normal OO
>programming rather than functional programming, which works well in the
>case of wanting to expand later the number of enum cases.
>-
>
>How much effort did you put into your review? A glance, a quick
>reading, or an in-depth study?
>Have followed the discussions. Used enums in Swift and other languages
>extensively.
>
>
> -- Howard.
>
> On 19 Dec 2017, at 12:58 pm, Ted Kremenek  wrote:
>
> 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 

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

2017-12-19 Thread Howard Lovatt via swift-evolution
As an aside: there seems to be increasingly comments about proposals that say:

  1. This was discussed at the evaluation stage and rejected. 
  2. This is how it is implemented in the patch.

And other comments along those lines. Neither the pre-proposal discussions nor 
the proposed implementation are intended to limit the scope of the review. 
Therefore I don’t think people should raise this as reasons. You should 
remember that the process is deliberately staged this way and different people 
may well be commenting (in fact the process rather assumes that people in the 
formal review will be a wider set of people). 

Anyway gripe over. 

Proposal link: 
https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md
What is your evaluation of the proposal?

+1/2

I only give this a half because whilst it is important I can see three issues:

  1. It doesn’t seem very Swift like to have a different rule, default 
non-exhaustive, for public as opposed to non-public. 

  2. It doesn’t seem very Swift like to have the default the unsafe case. 

  3. Other languages have better solutions - see below under other languages

Is the problem being addressed significant enough to warrant a change to Swift?

Yes, Swift ABI compatibility going forwards is important

Does this proposal fit well with the feel and direction of Swift?

No. As mentioned above different rules for public and a non-safe default don’t 
see that Swift like. 

If you have used other languages or libraries with a similar feature, how do 
you feel that this proposal compares to those?

Both Java and Scala have a better solution. In these languages enums (Scala 
calls them case classes) can implement protocols and the user of an enum rarely 
writes a switch statement, instead they call protocol methods. Enums in these 
languages are a fixed set of derived classes; i.e. normal OO programming rather 
than functional programming, which works well in the case of wanting to expand 
later the number of enum cases. 

How much effort did you put into your review? A glance, a quick reading, or an 
in-depth study?

Have followed the discussions. Used enums in Swift and other languages 
extensively. 

-- Howard.

> On 19 Dec 2017, at 12:58 pm, Ted Kremenek  wrote:
> 
> 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?
> 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-12-19 Thread Slava Pestov via swift-evolution
They would not be boxed, but there would be additional indirection required at 
runtime, using the same mechanism currently used for unspecialized generics.

Slava

> On Dec 19, 2017, at 6:42 PM, Kevin Ballard  wrote:
> 
> Isn’t this going to turn both structs and non-C-like enums into types that 
> need to be auto-boxed (as the client won’t be able to rely on knowing the 
> fixed size anymore)? This seems like a performance hazard.
> 
> -Kevin Ballard
> 
> On Dec 19, 2017, at 5:35 PM, Slava Pestov  > wrote:
> 
>> 
>> 
>>> On Dec 19, 2017, at 3:31 PM, Kevin Ballard via swift-evolution 
>>> > wrote:
>>> 
>>> So I guess I’m saying, I want more thought put on the topic of whether 
>>> enums defined in Swift should actually default to non-exhaustive, and I’m 
>>> now leaning towards the idea that they should remain exhaustive (but Obj-C 
>>> enums will still default to non-exhaustive).
>> 
>> This would introduce an inconsistency between enums and structs. Structs 
>> will not be fixed-contents by default (there’s a proposal coming for that), 
>> which means you will be able to add stored properties after the fact. For 
>> this reason it makes more sense to me to also make enums non-exhaustive by 
>> default so that new cases can be added.
>> 
>> Slava

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


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

2017-12-19 Thread Kevin Ballard via swift-evolution
Isn’t this going to turn both structs and non-C-like enums into types that need 
to be auto-boxed (as the client won’t be able to rely on knowing the fixed size 
anymore)? This seems like a performance hazard.

-Kevin Ballard

> On Dec 19, 2017, at 5:35 PM, Slava Pestov  wrote:
> 
> 
> 
>> On Dec 19, 2017, at 3:31 PM, Kevin Ballard via swift-evolution 
>>  wrote:
>> 
>> So I guess I’m saying, I want more thought put on the topic of whether enums 
>> defined in Swift should actually default to non-exhaustive, and I’m now 
>> leaning towards the idea that they should remain exhaustive (but Obj-C enums 
>> will still default to non-exhaustive).
> 
> This would introduce an inconsistency between enums and structs. Structs will 
> not be fixed-contents by default (there’s a proposal coming for that), which 
> means you will be able to add stored properties after the fact. For this 
> reason it makes more sense to me to also make enums non-exhaustive by default 
> so that new cases can be added.
> 
> Slava
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-12-19 Thread Slava Pestov via swift-evolution


> On Dec 19, 2017, at 3:31 PM, Kevin Ballard via swift-evolution 
>  wrote:
> 
> So I guess I’m saying, I want more thought put on the topic of whether enums 
> defined in Swift should actually default to non-exhaustive, and I’m now 
> leaning towards the idea that they should remain exhaustive (but Obj-C enums 
> will still default to non-exhaustive).

This would introduce an inconsistency between enums and structs. Structs will 
not be fixed-contents by default (there’s a proposal coming for that), which 
means you will be able to add stored properties after the fact. For this reason 
it makes more sense to me to also make enums non-exhaustive by default so that 
new cases can be added.

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


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

2017-12-19 Thread Xiaodi Wu via swift-evolution
On Tue, Dec 19, 2017 at 6:31 PM, Kevin Ballard via swift-evolution <
swift-evolution@swift.org> wrote:

>
> On Dec 19, 2017, at 2:58 PM, Ted Kremenek  wrote:
>
> https://github.com/apple/swift-evolution/blob/master/
> proposals/0192-non-exhaustive-enums.md
>
>
>-
>
>What is your evaluation of the proposal?
>
> Overall I like it, but I have some issues.
>
> I’m not completely sold yet on the idea that public enums should be
> non-exhaustive by default, as I believe every single public enum I’ve ever
> written definitely wants to be exhaustive. I’m tempted to say that enums
> exposed by frameworks that need to maintain future-compatibility (such as
> Apple’s frameworks) want non-exhaustive by default, but enums exposed by
> third-party frameworks that follow semantic versioning are likely to want
> exhaustive by default.
>
> In fact, this brings to mind another difference between enums in Apple
> frameworks and enums in third-party Swift frameworks, which is the former
> is exclusively C-compatible enums whereas the latter is going to have a lot
> of enums that carry associated values. I have no data to support this but
> I’m inclined to think that it’s more likely for C-compatible enums to want
> to be non-exhaustive than it is for enums carrying associated values to
> want to be non-exhaustive.
>
> So I guess I’m saying, I want more thought put on the topic of whether
> enums defined in Swift should actually default to non-exhaustive, and I’m
> now leaning towards the idea that they should remain exhaustive (but Obj-C
> enums will still default to non-exhaustive).
>

I think the proposal represents a very good summary of the pros and cons of
each approach. At the pre-proposal stage, all possible solutions (there are
only three: no default, default to exhaustive, or default to nonexhaustive)
were thoroughly explored, and the proposal as revised here represents a
thoughtful synthesis of the conversation and has a good justification for
the default proposed. I highly doubt that any more back-and-forth on this
will surface new arguments not already covered.


> --
>
> I don’t like that modules using @testable imports treat all enums as
> exhaustive. I can see why you want to do that, but being forced to handle
> non-exhaustive enums in unit tests seems like a valuable guard against
> accidentally publishing non-exhaustive enums that should be exhaustive.
>

On the contrary, I think that the proposal's behavior for `@testable` is
fully consistent and the best solution possible. It preserves the behavior
that `@testable` imports are treated as though internal, and it allows for
unit tests to have compile-time errors when unexpected cases are added. Any
time you want to test nonexhaustive behavior, you can import without
`@testable`.

--
>
> I’m really not a fan of using a ‘default’ case in non-exhaustive enums.
> This means that if new cases are added, the compiler can’t help me find my
> switches. I’d really like to have an alternative way of saying “here’s how
> to behave in the event of an unknown enum case” without also making that a
> catch-all for unspecified-but-known cases. You already brought up this
> issue in the alternatives section, where you stated
>
> Ultimately I decided not to include this in the proposal with the
> expectation is that switches over non-exhaustive enums should be uncommon.
>
>
> But since non-exhaustive enums will be the default, I think this _will_
> become quite common, if for no other reason than you’re using a library
> written by someone who forgot to mark enums as @exhaustive that really
> should be.
>
> Regarding the comment that a ‘future’ case is impossible to test, so is a
> ‘default’ case on a switch that is otherwise exhaustive. In the latter you
> can test it by commenting out one of your existing cases. But you can do
> that with ‘future’ too, just by renaming it to ‘default’ first.
>

This, too, I think, has been discussed quite thoroughly, and I think the
proposal synthesizes the discussion and presents the best possible solution.


> In the “Use-side” section it says that a switch without a default case
> will produce a warning in Swift 4 mode. But in Swift 4 mode all enums are
> exhaustive by default and the @exhaustive annotation does nothing. These
> two things can’t both be true or else Swift 4 mode will emit warnings on
> switches over enums that are very clearly supposed to be exhaustive enums.
>

This is curious. I wonder if C enums will be nonexhaustive in both Swift 4
and 5 mode, thereby triggering such warnings.

>
>-
>
>Is the problem being addressed significant enough to warrant a change
>to Swift?
>
> Yes
>
>
>-
>
>Does this proposal fit well with the feel and direction of Swift?
>
> Yes
>
>
>-
>
>How much effort did you put into your review? A glance, a quick
>reading, or an in-depth study?
>
> A quick reading, followed by a few re-readings as I composed this email.
>
> -Kevin Ballard
>
> 

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

2017-12-19 Thread Kevin Ballard via swift-evolution

> On Dec 19, 2017, at 2:58 PM, Ted Kremenek  wrote:
> https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md
>  
> 
> What is your evaluation of the proposal?
> 

Overall I like it, but I have some issues.

I’m not completely sold yet on the idea that public enums should be 
non-exhaustive by default, as I believe every single public enum I’ve ever 
written definitely wants to be exhaustive. I’m tempted to say that enums 
exposed by frameworks that need to maintain future-compatibility (such as 
Apple’s frameworks) want non-exhaustive by default, but enums exposed by 
third-party frameworks that follow semantic versioning are likely to want 
exhaustive by default.

In fact, this brings to mind another difference between enums in Apple 
frameworks and enums in third-party Swift frameworks, which is the former is 
exclusively C-compatible enums whereas the latter is going to have a lot of 
enums that carry associated values. I have no data to support this but I’m 
inclined to think that it’s more likely for C-compatible enums to want to be 
non-exhaustive than it is for enums carrying associated values to want to be 
non-exhaustive.

So I guess I’m saying, I want more thought put on the topic of whether enums 
defined in Swift should actually default to non-exhaustive, and I’m now leaning 
towards the idea that they should remain exhaustive (but Obj-C enums will still 
default to non-exhaustive).

--

I don’t like that modules using @testable imports treat all enums as 
exhaustive. I can see why you want to do that, but being forced to handle 
non-exhaustive enums in unit tests seems like a valuable guard against 
accidentally publishing non-exhaustive enums that should be exhaustive.

--

I’m really not a fan of using a ‘default’ case in non-exhaustive enums. This 
means that if new cases are added, the compiler can’t help me find my switches. 
I’d really like to have an alternative way of saying “here’s how to behave in 
the event of an unknown enum case” without also making that a catch-all for 
unspecified-but-known cases. You already brought up this issue in the 
alternatives section, where you stated

> Ultimately I decided not to include this in the proposal with the expectation 
> is that switches over non-exhaustive enums should be uncommon.


But since non-exhaustive enums will be the default, I think this _will_ become 
quite common, if for no other reason than you’re using a library written by 
someone who forgot to mark enums as @exhaustive that really should be.

Regarding the comment that a ‘future’ case is impossible to test, so is a 
‘default’ case on a switch that is otherwise exhaustive. In the latter you can 
test it by commenting out one of your existing cases. But you can do that with 
‘future’ too, just by renaming it to ‘default’ first.

--

In the “Use-side” section it says that a switch without a default case will 
produce a warning in Swift 4 mode. But in Swift 4 mode all enums are exhaustive 
by default and the @exhaustive annotation does nothing. These two things can’t 
both be true or else Swift 4 mode will emit warnings on switches over enums 
that are very clearly supposed to be exhaustive enums.
> Is the problem being addressed significant enough to warrant a change to 
> Swift?
> 
Yes
> Does this proposal fit well with the feel and direction of Swift?
> 
Yes
> How much effort did you put into your review? A glance, a quick reading, or 
> an in-depth study?
> 
A quick reading, followed by a few re-readings as I composed this email.

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