Re: [swift-evolution] The Non-Exhaustive Enums proposal kills one of Swift's top features - change proposal

2017-12-23 Thread Cheyo Jimenez via swift-evolution


> On Dec 23, 2017, at 4:15 PM, Slava Pestov via swift-evolution 
>  wrote:
> 
> 
> 
>> On Dec 23, 2017, at 3:47 PM, Thomas Roughton via swift-evolution 
>>  wrote:
>> 
>> 
>>> On 24/12/2017, at 9:40 AM, Cheyo Jimenez via swift-evolution 
>>>  wrote:
>>> 
>>> What are your thoughts on `final switch` as a way to treat any enum as 
>>> exhaustible?
>>> https://dlang.org/spec/statement.html#FinalSwitchStatement
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
>> 
>> I’d be very much in favour of this (qualms about the naming of the ‘final’ 
>> keyword aside - ‘complete’ or ‘exhaustive’ reads better to me). 
>> 
>> Looking back at the proposal, I noticed that something similar was mentioned 
>> that I earlier missed. In the proposal, it says:
>> 
>>> However, this results in some of your code being impossible to test, since 
>>> you can't write a test that passes an unknown value to this switch.
>> 
>> Is that strictly true? Would it be theoretically possible for the compiler 
>> to emit or make accessible a special ‘test’ case for non-exhaustive enums 
>> that can only be used in test modules or e.g. by a 
>> ‘EnumName(testCaseNamed:)’, constructor? There is  potential for abuse there 
>> but it would address that particular issue. 
>> 
>> Regardless, I still feel something like a ‘final switch’ is necessary if 
>> this proposal is introduced, and that it fits with the ‘progressive 
>> disclosure’ notion; once you learn this keyword you have a means to check 
>> for completeness, but people unaware of it could just use a ‘default’ case 
>> as per usual and not be concerned with exhaustiveness checking. 
> 
> My general philosophy with syntax sugar is that it should do more than just 
> remove a constant number of tokens. Basically you’re saying that
> 
> final switch x {}
> 
> just expands to
> 
> switch x { // edited
> default: fatalError()
> }
> 
> I don’t think a language construct like this carries its weight.

Having the ability to treat a non exhaustive enum as if it where exhaustive is 
not the same as 

switch x {
default : fatalError()
}

The above will happily let me omit currently compile time known cases.  Perhaps 
‘final switch’ is not the best but I can’t think of another way to semantically 
“cast” a non exhaustive as exhaustive. Essentially what I believe we want is a 
way to treat a non exhaustive as exhaustive during compile time, on the client 
side. 

It would be cool if we instead repurposed the swift “case _” to handle all 
compile time known cases and default could then handle all unknown future cases 
in an non exhaustive enum. 

public enum x {a, b, c, d}

switch x { // x is non exhaustive here
  case a: print("case a")
  case _ : print(“known cases b c or d”) // sugar for cases b, c, d which are 
known during compile time. Expanded to mean case b, c, d. 
default: fatalError() // future unknown cases
}

I don’t think this would would break any code since all enums have been 
exhaustive. No new syntax would be added and now there would be a meaningful 
difference between compile time known cases (case _) vs compile time unknown 
future cases (default). 


> 
> For example, generics have a multiplicative effect on code size — they 
> prevent you from having to write an arbitrary number of versions of the same 
> algorithm for different concrete types.
> 
> Another example is optionals — while optionals don’t necessarily make code 
> shorter, they make it more understandable, and having optionals in the 
> language rules out entire classes of errors at compile time.
> 
> On the other hand, a language feature that just reduces the number of tokens 
> without any second-order effects makes code harder to read, the language 
> harder to learn, and the compiler buggier and harder to maintain without much 
> benefit. So I think for the long term health of the language we should avoid 
> ‘shortcuts’ like this.
> 
> Slava
> ___
> 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] The Non-Exhaustive Enums proposal kills one of Swift's top features - change proposal

2017-12-23 Thread Slava Pestov via swift-evolution
Hi Thomas,

I see what you mean now. I think in this case I would prefer to just spell this 
as ‘switch x { … unknown: … }’ vs ‘switch x { … default: … }’. But yes, a few 
people have signaled support for such a feature and I think it’s worth 
discussing.

Slava

> On Dec 23, 2017, at 4:27 PM, Thomas Roughton  wrote:
> 
> Hi Slava,
> 
> I think we may be referring to different things. For whatever it’s worth, I 
> agree with your reasoning on all the points you brought up. I also don’t 
> think having a 'default: fatalError()’ case is a good idea because then a 
> library change can cause crashes in a running version of an application.
> 
> What I mean by some sort of ‘complete switch’ statement is that it would be 
> compiled as per a normal ‘switch’ but error at compile time if it’s not 
> complete against the known set of cases as compile time. Assuming an enum 
> with known cases [a, b] at compile time,
> 
> switch nonExhaustiveEnum {
>   case a:
>   print(“a”)
>   case b:
>   print(“b”)
>   default:
>   break
> }
> 
> would be exactly equivalent to:
> 
> complete switch nonExhaustiveEnum {
>   case a:
>   print(“a”)
>   case b:
>   print(“b”)
>   unknown:  // the ‘unknown’ case would only be required for 
> non-exhaustive enums
>   break
> }
> 
> where the keywords ‘complete’ and ‘unknown’ are up for debate. If, however, 
> the programmer wrote:
> 
> complete switch nonExhaustiveEnum {
>   case a:
>   print(“a”)
>   unknown:
>   break
> }
> 
> the compiler would give an error that there are unhandled cases in the switch 
> statement, whereas
> 
> switch nonExhaustiveEnum {
>   case a:
>   print(“a”)
>   default:
>   break
> }
> 
> would compile without issue. If a user didn’t know about the existence of the 
> ‘complete switch’ construct, they could just use normal ‘switch’ statements 
> and miss out on the completeness checking.
> 
> Thomas
> 
>> On 24/12/2017, at 1:15 PM, Slava Pestov > > wrote:
>> 
>> 
>> 
>>> On Dec 23, 2017, at 3:47 PM, Thomas Roughton via swift-evolution 
>>> > wrote:
>>> 
>>> 
>>> On 24/12/2017, at 9:40 AM, Cheyo Jimenez via swift-evolution 
>>> > wrote:
 
 What are your thoughts on `final switch` as a way to treat any enum as 
 exhaustible?
 https://dlang.org/spec/statement.html#FinalSwitchStatement 
 ___
 swift-evolution mailing list
 swift-evolution@swift.org 
 https://lists.swift.org/mailman/listinfo/swift-evolution 
 
>>> 
>>> I’d be very much in favour of this (qualms about the naming of the ‘final’ 
>>> keyword aside - ‘complete’ or ‘exhaustive’ reads better to me). 
>>> 
>>> Looking back at the proposal, I noticed that something similar was 
>>> mentioned that I earlier missed. In the proposal, it says:
>>> 
 However, this results in some of your code being impossible to test, since 
 you can't write a test that passes an unknown value to this switch.
>>> 
>>> Is that strictly true? Would it be theoretically possible for the compiler 
>>> to emit or make accessible a special ‘test’ case for non-exhaustive enums 
>>> that can only be used in test modules or e.g. by a 
>>> ‘EnumName(testCaseNamed:)’, constructor? There is  potential for abuse 
>>> there but it would address that particular issue. 
>>> 
>>> Regardless, I still feel something like a ‘final switch’ is necessary if 
>>> this proposal is introduced, and that it fits with the ‘progressive 
>>> disclosure’ notion; once you learn this keyword you have a means to check 
>>> for completeness, but people unaware of it could just use a ‘default’ case 
>>> as per usual and not be concerned with exhaustiveness checking. 
>> 
>> My general philosophy with syntax sugar is that it should do more than just 
>> remove a constant number of tokens. Basically you’re saying that
>> 
>> final switch x {}
>> 
>> just expands to
>> 
>> swift x {
>> default: fatalError()
>> }
>> 
>> I don’t think a language construct like this carries its weight.
>> 
>> For example, generics have a multiplicative effect on code size — they 
>> prevent you from having to write an arbitrary number of versions of the same 
>> algorithm for different concrete types.
>> 
>> Another example is optionals — while optionals don’t necessarily make code 
>> shorter, they make it more understandable, and having optionals in the 
>> language rules out entire classes of errors at compile time.
>> 
>> On the other hand, a language feature that just reduces the number of tokens 
>> 

Re: [swift-evolution] The Non-Exhaustive Enums proposal kills one of Swift's top features - change proposal

2017-12-23 Thread Thomas Roughton via swift-evolution
Hi Slava,

I think we may be referring to different things. For whatever it’s worth, I 
agree with your reasoning on all the points you brought up. I also don’t think 
having a 'default: fatalError()’ case is a good idea because then a library 
change can cause crashes in a running version of an application.

What I mean by some sort of ‘complete switch’ statement is that it would be 
compiled as per a normal ‘switch’ but error at compile time if it’s not 
complete against the known set of cases as compile time. Assuming an enum with 
known cases [a, b] at compile time,

switch nonExhaustiveEnum {
case a:
print(“a”)
case b:
print(“b”)
default:
break
}

would be exactly equivalent to:

complete switch nonExhaustiveEnum {
case a:
print(“a”)
case b:
print(“b”)
unknown:  // the ‘unknown’ case would only be required for 
non-exhaustive enums
break
}

where the keywords ‘complete’ and ‘unknown’ are up for debate. If, however, the 
programmer wrote:

complete switch nonExhaustiveEnum {
case a:
print(“a”)
unknown:
break
}

the compiler would give an error that there are unhandled cases in the switch 
statement, whereas

switch nonExhaustiveEnum {
case a:
print(“a”)
default:
break
}

would compile without issue. If a user didn’t know about the existence of the 
‘complete switch’ construct, they could just use normal ‘switch’ statements and 
miss out on the completeness checking.

Thomas

> On 24/12/2017, at 1:15 PM, Slava Pestov  wrote:
> 
> 
> 
>> On Dec 23, 2017, at 3:47 PM, Thomas Roughton via swift-evolution 
>> > wrote:
>> 
>> 
>> On 24/12/2017, at 9:40 AM, Cheyo Jimenez via swift-evolution 
>> > wrote:
>>> 
>>> What are your thoughts on `final switch` as a way to treat any enum as 
>>> exhaustible?
>>> https://dlang.org/spec/statement.html#FinalSwitchStatement 
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org 
>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>> 
>> 
>> I’d be very much in favour of this (qualms about the naming of the ‘final’ 
>> keyword aside - ‘complete’ or ‘exhaustive’ reads better to me). 
>> 
>> Looking back at the proposal, I noticed that something similar was mentioned 
>> that I earlier missed. In the proposal, it says:
>> 
>>> However, this results in some of your code being impossible to test, since 
>>> you can't write a test that passes an unknown value to this switch.
>> 
>> Is that strictly true? Would it be theoretically possible for the compiler 
>> to emit or make accessible a special ‘test’ case for non-exhaustive enums 
>> that can only be used in test modules or e.g. by a 
>> ‘EnumName(testCaseNamed:)’, constructor? There is  potential for abuse there 
>> but it would address that particular issue. 
>> 
>> Regardless, I still feel something like a ‘final switch’ is necessary if 
>> this proposal is introduced, and that it fits with the ‘progressive 
>> disclosure’ notion; once you learn this keyword you have a means to check 
>> for completeness, but people unaware of it could just use a ‘default’ case 
>> as per usual and not be concerned with exhaustiveness checking. 
> 
> My general philosophy with syntax sugar is that it should do more than just 
> remove a constant number of tokens. Basically you’re saying that
> 
> final switch x {}
> 
> just expands to
> 
> swift x {
> default: fatalError()
> }
> 
> I don’t think a language construct like this carries its weight.
> 
> For example, generics have a multiplicative effect on code size — they 
> prevent you from having to write an arbitrary number of versions of the same 
> algorithm for different concrete types.
> 
> Another example is optionals — while optionals don’t necessarily make code 
> shorter, they make it more understandable, and having optionals in the 
> language rules out entire classes of errors at compile time.
> 
> On the other hand, a language feature that just reduces the number of tokens 
> without any second-order effects makes code harder to read, the language 
> harder to learn, and the compiler buggier and harder to maintain without much 
> benefit. So I think for the long term health of the language we should avoid 
> ‘shortcuts’ like this.
> 
> Slava

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


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

2017-12-23 Thread Slava Pestov via swift-evolution
Hi Dave,

The broader problem is being considered holistically, and we’re designing and 
implementing various pieces of the solution as part of the ABI stability effort 
for Swift 5. Some of these pieces impact the language, hence you’ll be seeing 
some evolution proposals. Non-exhaustive enums is one part, the inlinable 
proposal out for review right now is another part. There are a few more related 
proposals in the pipeline also.

Perhaps we need to do a better job of explaining how these things all tie 
together. In the mean time you can read about the overall design here: 
https://github.com/apple/swift/blob/master/docs/LibraryEvolution.rst 


Slava

> On Dec 23, 2017, at 11:17 AM, Dave DeLong via swift-evolution 
>  wrote:
> 
> Continuing on this vein, there is another huge reason this proposal is 
> incomplete and won’t solve the problem.
> 
> This proposal, as I outlined previously, is all about binary compatibility 
> and functional resilience in the face of changing libraries. However, it 
> falls woefully short by only considering the binary implications of changing 
> enums.
> 
> The problem of binary compatibility extends *far* beyond the mutation of 
> enums between library versions. By only considering the “enum problem”, we 
> are ignoring a much larger and worse problem that will be even easier for 
> libraries to succumb to. It’s easy as a library author to inadvertently 
> rename a method or change the type of a parameter, or add a parameter, or 
> change the return type, or change the implementation semantics, or remove a 
> type, or remove a function, in such a way that a linking app cannot handle. 
> This is why the burden of binary compatibility rightfully rests on library 
> authors, and not app authors. 
> 
> The thing that changes has the responsibility to maintain compatibility for 
> the thing that hasn’t changed.
> 
> We should absolutely not implement this proposal; it only addresses a single 
> portion of a very large problem. Instead, we should figure out what the 
> broader binary compatibility story is. If we can answer *that* and provide 
> the necessary features to address it, then enum resilience will naturally 
> fall out of it. Focusing on the enum problem is focusing on the wrong problem.
> 
> Dave
> 
>> On Dec 21, 2017, at 11:02 AM, Dave DeLong > > wrote:
>> 
>> I realized further why we should not implement this proposal: It forces the 
>> problem of binary compatibility on the app developer, when experience has 
>> shown us that problem is better handled by the libraries.
>> 
>> Binary Compatibility
>> 
>> “Binary compatibility” is the notion that, even if the libraries you link 
>> against change, your app will still behave as it did when it was first 
>> compiled. For Swift apps these days, we don’t really have this problem, 
>> *yet*. We do have the problem of “binary compatibility” with Apple-provided 
>> frameworks, but those are all written in Objective-C, and so the question of 
>> “Swift” binary compatibility is still up-in-the-air.
>> 
>> Post-ABI stability, we still won’t have much issue with swift binary 
>> compatibility on Apple platforms, because there isn’t a mechanism to ship a 
>> framework to your users independently of an app update. So from the app POV, 
>> none of this will be a problem for Apple platform developers.
>> 
>> It will be a problem for non-Apple platform developers. As a simple example, 
>> let’s say I write a web app in Swift, and deploy it to a server that has 
>> some built-in Swift-on-the-server libraries. Here, my Swift app is decoupled 
>> from the libraries, and either one can update independently of each other. 
>> If the server owner decides to update from Swift 6 to Swift 6.1, that’s 
>> cool. But my web app should continue to run and behave *as if* the server 
>> were still running Swift 6, because it has not been re-compiled to use Swift 
>> 6.1 features.
>> 
>> This is the situation today on Apple platforms. Every app deployed to an 
>> Apple device includes a little piece of information in the executable file 
>> indicating which SDK was used to compile the app. At runtime, the system 
>> frameworks read this value and then alter their behavior accordingly. This 
>> is why apps written against the iOS 9 SDK continue to work on iOS 11 
>> devices; UIKit and friends are altering their behavior to provide iOS 9 
>> semantics. 
>> 
>> This is “binary compatibility”: the binary (your app) continues to be 
>> compatible with the dynamically linked frameworks present on the system, 
>> even though those frameworks may change.
>> 
>> When you have a setup where the frameworks do NOT provide binary 
>> compatibility, you end up in DLL Hell [1]. This is the same frustrating 
>> scenario when you’re in when you’re doing stuff with homebrew and find that 
>> this package you want 

Re: [swift-evolution] The Non-Exhaustive Enums proposal kills one of Swift's top features - change proposal

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


> On Dec 23, 2017, at 3:47 PM, Thomas Roughton via swift-evolution 
>  wrote:
> 
> 
> On 24/12/2017, at 9:40 AM, Cheyo Jimenez via swift-evolution 
> > wrote:
>> 
>> What are your thoughts on `final switch` as a way to treat any enum as 
>> exhaustible?
>> https://dlang.org/spec/statement.html#FinalSwitchStatement 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org 
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> 
> 
> I’d be very much in favour of this (qualms about the naming of the ‘final’ 
> keyword aside - ‘complete’ or ‘exhaustive’ reads better to me). 
> 
> Looking back at the proposal, I noticed that something similar was mentioned 
> that I earlier missed. In the proposal, it says:
> 
>> However, this results in some of your code being impossible to test, since 
>> you can't write a test that passes an unknown value to this switch.
> 
> Is that strictly true? Would it be theoretically possible for the compiler to 
> emit or make accessible a special ‘test’ case for non-exhaustive enums that 
> can only be used in test modules or e.g. by a ‘EnumName(testCaseNamed:)’, 
> constructor? There is  potential for abuse there but it would address that 
> particular issue. 
> 
> Regardless, I still feel something like a ‘final switch’ is necessary if this 
> proposal is introduced, and that it fits with the ‘progressive disclosure’ 
> notion; once you learn this keyword you have a means to check for 
> completeness, but people unaware of it could just use a ‘default’ case as per 
> usual and not be concerned with exhaustiveness checking. 

My general philosophy with syntax sugar is that it should do more than just 
remove a constant number of tokens. Basically you’re saying that

final switch x {}

just expands to

swift x {
default: fatalError()
}

I don’t think a language construct like this carries its weight.

For example, generics have a multiplicative effect on code size — they prevent 
you from having to write an arbitrary number of versions of the same algorithm 
for different concrete types.

Another example is optionals — while optionals don’t necessarily make code 
shorter, they make it more understandable, and having optionals in the language 
rules out entire classes of errors at compile time.

On the other hand, a language feature that just reduces the number of tokens 
without any second-order effects makes code harder to read, the language harder 
to learn, and the compiler buggier and harder to maintain without much benefit. 
So I think for the long term health of the language we should avoid ‘shortcuts’ 
like this.

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


Re: [swift-evolution] The Non-Exhaustive Enums proposal kills one of Swift's top features - change proposal

2017-12-23 Thread Thomas Roughton via swift-evolution

> On 24/12/2017, at 9:40 AM, Cheyo Jimenez via swift-evolution 
>  wrote:
> 
> What are your thoughts on `final switch` as a way to treat any enum as 
> exhaustible?
> https://dlang.org/spec/statement.html#FinalSwitchStatement
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution


I’d be very much in favour of this (qualms about the naming of the ‘final’ 
keyword aside - ‘complete’ or ‘exhaustive’ reads better to me). 

Looking back at the proposal, I noticed that something similar was mentioned 
that I earlier missed. In the proposal, it says:

> However, this results in some of your code being impossible to test, since 
> you can't write a test that passes an unknown value to this switch.

Is that strictly true? Would it be theoretically possible for the compiler to 
emit or make accessible a special ‘test’ case for non-exhaustive enums that can 
only be used in test modules or e.g. by a ‘EnumName(testCaseNamed:)’, 
constructor? There is  potential for abuse there but it would address that 
particular issue. 

Regardless, I still feel something like a ‘final switch’ is necessary if this 
proposal is introduced, and that it fits with the ‘progressive disclosure’ 
notion; once you learn this keyword you have a means to check for completeness, 
but people unaware of it could just use a ‘default’ case as per usual and not 
be concerned with exhaustiveness checking. 

Thomas

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


Re: [swift-evolution] Evaluating the case of an enum with associated values as a bool

2017-12-23 Thread Ethan Diamond via swift-evolution
Is there a reason the team wants to do synthesis instead of other options? If 
that’s no longer assignment, it’s going to break a lot of code. 

Sent from my iPhone

> On Dec 23, 2017, at 1:19 PM, Dave Abrahams  wrote:
> 
> 
> 
> Sent from my iPhone
> 
>> On Dec 21, 2017, at 2:33 PM, Ethan Diamond  wrote:
>> 
>> 
>>> On Dec 21, 2017, at 10:59 AM, Dave Abrahams  wrote:
>>> 
>>> 
>>> 
 On Dec 21, 2017, at 10:19 AM, Ethan Diamond  
 wrote:
 
 Just to clarify, Dave -
 
 What happens there if one case has associated values
>>> 
 and one has an associated value thats an optional? 
 
 Enum A {
case x(String?)
case y
 }
 
 let a = A.x(nil)
>>> 
>>> A.x is String??
>> 
>> This was assigning .x to a, not evaluating a synthesized value
> 
> And I was making an assertion, not asking a question  
>> 
>>> 
 a.y // What's the result?
>>> 
>>> nil as Optional
>>> 
 a.x // Would produce a double optional, which are clumsy to nil check
>>> 
>>> They’re a fact of life.  If that’s a problem, we should consider fixing it, 
>>> but it’s orthogonal to this one.
>>> 
 
 I'm not a fan of solving this via synthesis in general. We have metatypes 
 for classes/structs/protocols, which are useful in all sorts of 
 situations. Cases are essentially "types" of enums. Why not have case 
 metatypes? They're useful for the same reasons class types are, and 
 there's already precedence in the language for syntax.
>>> 
>>> You mean “precedent?”  OK, but I don’t see how it helps with any of the 
>>> same problems as synthesized properties for cases do.
>>> 
>> 
>> I’m not really sure what the problems synthesized properties are trying to 
>> solve are. Chris brought them up as a possible solution to my pain point, 
>> which they only solve partially. Checking for a case I don’t know up front 
>> (for example, comparing the cases of two values) still isn’t covered. 
>> 
 
 
 
> On Thu, Dec 21, 2017 at 7:14 AM Dave Abrahams  wrote:
> IIRC what we discussed was synthesizing  members of type 
> Optional which could then be checked against nil. 
> 
> if _ = x.failure { ... }
> if x.failure != nil { ... }
> if let r = x.success {...}
> 
> IMO synthesizing predicates would be a huge missed opportunity by 
> comparison
> 
> Sent from my iPhone
> 
>> On Dec 20, 2017, at 1:31 PM, Chris Lattner via swift-evolution 
>>  wrote:
>> 
>> In the past, we’ve discussed synthesizing predicate members onto enums.  
>> E.g. given:
>> 
>> enum E {
>>   case X
>>   case Y(Int)
>> }
>> 
>> you’d get something like:
>> 
>> extension E {
>>   func isX() -> Bool { return self == .X }
>>   func getY() -> Int? { … }
>> }
>> 
>> which would solve the client side of this nicely.
>> 
>> -Chris
>> 
>> 
>> 
>>> On Dec 20, 2017, at 11:24 AM, Ethan Diamond via swift-evolution 
>>>  wrote:
>>> 
>>> Sorry all for attaching the original post to the Non-Exhaustive enums 
>>> thread. I"m moving it down to it's own thread. 
>>> 
>>> My understanding is I'm not allowed to write up a proposal unless I 
>>> have the time to implement it. Is that still true? This is a major pain 
>>> point for me to avoid having to write things like this:
>>> 
>>> if case .search = presenter.state { return true } else { return false }
>>> 
>>> Side note: Thanks Kevin, didn't know you could nest enums in switches 
>>> like that. Super helpful!
>>> 
>>> --
>>> I thought I would add another case that isn’t possible with current 
>>> syntax (so far as I’m aware).  You can’t negate the comparison to do 
>>> something for all cases except a particular case.  You have to have an 
>>> empty if block and use the else block, or have an empty case in a 
>>> switch statement and use the default.
>>> 
>>> enum Enum {
>>>   case a(param: String)
>>>   case b(param: String)
>>>   case c(param: String)
>>> }
>>> 
>>> let enumeration: Enum = .a(param: "Hi")
>>> 
>>> if !(case .a = enumeration) {
>>>   // Do something
>>> }
>>> 
>>> — Charles
>>> 
>>> > On Dec 20, 2017, at 9:55 AM, Kevin Nattinger via swift-evolution 
>>> >  wrote:
>>> > 
>>> > I agree this would be useful. At the moment I have to hack around it 
>>> > with things like `var isFoo: Bool { if case .foo = self …`* with 
>>> > cases I commonly need, but this is definitely a feature that has come 
>>> > up before and I support. It is potentially related to getting the 
>>> > values through an accessor, which has also 

Re: [swift-evolution] [swift-evolution-announce] [REVIEW] SE-0193 - Cross-module inlining and specialization

2017-12-23 Thread Chris Lattner via swift-evolution
On Dec 22, 2017, at 9:12 PM, Slava Pestov  wrote:
>> Deployment platform makes more sense, but I still can't envision a real use 
>> case. What sorts of `bar()` would hypothetically be necessary for iOS 15 but 
>> not 16? Why would a third-party library need to increase its inlining 
>> availability for an app based on deployment platform?
> 
> A better example would be if bar() was itself only available in iOS 16:
> 
> @available(iOS 15)
> @available(inlinable: iOS 16)
> public func foo() {
>   bar()
> }
> 
> @available(iOS 16)
> public func bar() { … }
> 
> Suppose your app calls foo() and deploys to iOS 15. Then you cannot inline 
> foo(), because bar() does not exist on iOS 15. (Presumably, foo() had a 
> different implementation on iOS 15). But if you’re deploying to iOS 16, all 
> is well, and you can inline foo(), which results in your app directly calling 
> bar().

Thanks, that’s a much better example.

>> I'm quite sure that the reason you inverted your "abiPublic" example is 
>> because of the same issue. Intuitively, you would want to mark something as 
>> "available" in version N and then maybe some special kind of "available" in 
>> version N+1 (which @available(inlinable) would be). But 
>> @available(linkerSymbol), as you spell it, suffers from a similar problem to 
>> that of @available(unavailable): it's _not_ a special kind of API 
>> availability, but rather indicates that something is less-than-available. 
>> That is, you would use it to indicate that something is available as ABI but 
>> not as API. In that sense, it extends the "mess" we have with 
>> @available(unavailable).
> 
> I don’t think it’s quite the same thing as @available(unavailable). An 
> @available(abiPublic) symbol would still be declared to have internal 
> visibility, so in this case the @available attribute makes it strictly more 
> visible than it would be without. We’re not going to spell it as 
> ‘@available(abiPublic) public’, which indeed would be confusing because the 
> symbol is not actually public at the source level.

Right.  The bug here is with @available(unavailable).  Its design is clearly 
broken and oxymoronic.  That doesn’t make all of @available broken.

-Chris


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


Re: [swift-evolution] [swift-evolution-announce] [REVIEW] SE-0193 - Cross-module inlining and specialization

2017-12-23 Thread Chris Lattner via swift-evolution


> On Dec 22, 2017, at 9:08 PM, Slava Pestov  wrote:
> 
> 
> 
>> On Dec 22, 2017, at 9:55 AM, Chris Lattner  wrote:
> 
>> When and if we add private cases to enums, we’ll need to be able to 
>> associate an availability range with an “exhaustive” marker.  When/if that 
>> happens, then yes, we should do so through @available(exhaustive: iOS41, *). 
>>The @exhaustive attribute will become sugar for “born exhaustive”, 
>> because in the absence of private cases the availability range doesn’t 
>> matter (AFAIK).
> 
> It still matters if the enum was not “born exhaustive”. Recall that 
> non-exhaustive enums and non-fixed contents structs are address-only types, 
> because we don’t know their size at compile time and so they must be passed 
> indirectly. So if your framework defines a non-exhaustive enum and a function 
> taking or returning this enum, the calling convention will change if the enum 
> becomes exhaustive (unless one of its cases is address-only for some other 
> reason). So we will need to use availability ranges to declare that an enum 
> became exhaustive after the fact. Such an enum will still be treated as 
> non-exhaustive in the calling convention, but can otherwise be manipulated 
> directly (as long as your deployment target is more recent than when it 
> became exhaustive).

Ok, makes sense to me.  This is even more reason to provide a framework that 
scales to these unusual cases. :-)

-Chris

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


Re: [swift-evolution] Evaluating the case of an enum with associated values as a bool

2017-12-23 Thread Dave Abrahams via swift-evolution


Sent from my iPhone

> On Dec 21, 2017, at 2:33 PM, Ethan Diamond  wrote:
> 
> 
>> On Dec 21, 2017, at 10:59 AM, Dave Abrahams  wrote:
>> 
>> 
>> 
>>> On Dec 21, 2017, at 10:19 AM, Ethan Diamond  wrote:
>>> 
>>> Just to clarify, Dave -
>>> 
>>> What happens there if one case has associated values
>> 
>>> and one has an associated value thats an optional? 
>>> 
>>> Enum A {
>>>case x(String?)
>>>case y
>>> }
>>> 
>>> let a = A.x(nil)
>> 
>> A.x is String??
> 
> This was assigning .x to a, not evaluating a synthesized value

And I was making an assertion, not asking a question  
> 
>> 
>>> a.y // What's the result?
>> 
>> nil as Optional
>> 
>>> a.x // Would produce a double optional, which are clumsy to nil check
>> 
>> They’re a fact of life.  If that’s a problem, we should consider fixing it, 
>> but it’s orthogonal to this one.
>> 
>>> 
>>> I'm not a fan of solving this via synthesis in general. We have metatypes 
>>> for classes/structs/protocols, which are useful in all sorts of situations. 
>>> Cases are essentially "types" of enums. Why not have case metatypes? 
>>> They're useful for the same reasons class types are, and there's already 
>>> precedence in the language for syntax.
>> 
>> You mean “precedent?”  OK, but I don’t see how it helps with any of the same 
>> problems as synthesized properties for cases do.
>> 
> 
> I’m not really sure what the problems synthesized properties are trying to 
> solve are. Chris brought them up as a possible solution to my pain point, 
> which they only solve partially. Checking for a case I don’t know up front 
> (for example, comparing the cases of two values) still isn’t covered. 
> 
>>> 
>>> 
>>> 
 On Thu, Dec 21, 2017 at 7:14 AM Dave Abrahams  wrote:
 IIRC what we discussed was synthesizing  members of type Optional 
 which could then be checked against nil. 
 
 if _ = x.failure { ... }
 if x.failure != nil { ... }
 if let r = x.success {...}
 
 IMO synthesizing predicates would be a huge missed opportunity by 
 comparison
 
 Sent from my iPhone
 
> On Dec 20, 2017, at 1:31 PM, Chris Lattner via swift-evolution 
>  wrote:
> 
> In the past, we’ve discussed synthesizing predicate members onto enums.  
> E.g. given:
> 
> enum E {
>   case X
>   case Y(Int)
> }
> 
> you’d get something like:
> 
> extension E {
>   func isX() -> Bool { return self == .X }
>   func getY() -> Int? { … }
> }
> 
> which would solve the client side of this nicely.
> 
> -Chris
> 
> 
> 
>> On Dec 20, 2017, at 11:24 AM, Ethan Diamond via swift-evolution 
>>  wrote:
>> 
>> Sorry all for attaching the original post to the Non-Exhaustive enums 
>> thread. I"m moving it down to it's own thread. 
>> 
>> My understanding is I'm not allowed to write up a proposal unless I have 
>> the time to implement it. Is that still true? This is a major pain point 
>> for me to avoid having to write things like this:
>> 
>> if case .search = presenter.state { return true } else { return false }
>> 
>> Side note: Thanks Kevin, didn't know you could nest enums in switches 
>> like that. Super helpful!
>> 
>> --
>> I thought I would add another case that isn’t possible with current 
>> syntax (so far as I’m aware).  You can’t negate the comparison to do 
>> something for all cases except a particular case.  You have to have an 
>> empty if block and use the else block, or have an empty case in a switch 
>> statement and use the default.
>> 
>> enum Enum {
>>   case a(param: String)
>>   case b(param: String)
>>   case c(param: String)
>> }
>> 
>> let enumeration: Enum = .a(param: "Hi")
>> 
>> if !(case .a = enumeration) {
>>   // Do something
>> }
>> 
>> — Charles
>> 
>> > On Dec 20, 2017, at 9:55 AM, Kevin Nattinger via swift-evolution 
>> >  wrote:
>> > 
>> > I agree this would be useful. At the moment I have to hack around it 
>> > with things like `var isFoo: Bool { if case .foo = self …`* with cases 
>> > I commonly need, but this is definitely a feature that has come up 
>> > before and I support. It is potentially related to getting the values 
>> > through an accessor, which has also come up several times.
>> > 
>> > Sidenote, your `switch` example is actually trivial with existing 
>> > syntax:
>> > 
>> > switch enumeration {
>> > case .a(.c(let param)): // or just .a(.c) if you don't need the value
>> > print(param)
>> > default:
>> > break
>> > }
>> > 
>> > I use this from time to time switching over, e.g., optional 

Re: [swift-evolution] The Non-Exhaustive Enums proposal kills one of Swift's top features - change proposal

2017-12-23 Thread Cheyo Jimenez via swift-evolution


> On Dec 21, 2017, at 9:49 AM, Ignacio Soto via swift-evolution 
>  wrote:
> 
> I think I speak for the entire Swift community when I say that Swift's enums, 
> together with the ability to switch over them exhaustively and having 
> compile-time guarantees, is one of the best features in Swift. I'm regularly 
> annoyed by this when writing other languages like Java and JS (default: throw 
> new IllegalArgumentException();)
> 
> Now, that's not to say I don't understand why this proposal is necessary. I 
> totally get it, and the existing decisions make a lot of sense to me. But I'd 
> like us to introduce this while maintaining the ability to guarantee 
> exhaustive switch statements, no matter how the enum was defined.
> 
> Example: imagine a theoretical SampleKit defines:
> public enum E {
> case A
> case B
> }
> 
> It's implicitly non-exhaustive, possibly because the author was not aware of 
> the default (which would likely happen often), or possibly because they made 
> a conscious decision, as they expect to expand the cases in the future.
> 
> In my app, I use SampleKit and decide that I want to make sure I handle all 
> cases:
> 
> switch e {
> case A: break
> case B: break
> default: break // This becomes necessary
> }
> 
> As the proposal stands right now, I'm forced to handle any future cases. 
> That's fine. What's not fine in my opinion, is that in doing so I lose the 
> ability to keep this exhaustiveness moving forward. If I update SampleKit to 
> v2.0, I want to know at compile-time if there are new cases I need to be 
> aware of (instead of going to some generic handling path). Instead, I’m left 
> in the same place I would in other languages like Java or JS:
> 
> // No error :(
> switch e {
> case A: break
> case B: break
> default: break
> }
> 
> Proposed Solution
> 
> What I’m proposing is that we introduce a new keyword, unknown (or a better 
> name), that serves as a way to handle cases that aren’t yet known, but not 
> those that are.
> 
> // Error: missing case C
> switch e {
> case A: break
> case B: break
> unknown: break // Would handle future cases
> }
> 

What are your thoughts on `final switch` as a way to treat any enum as 
exhaustible?
https://dlang.org/spec/statement.html#FinalSwitchStatement


> With this, you shouldn’t be able to use default AND unknown at the same time, 
> as default implicitly includes unknown.
> 
> Thanks for reading, and I hope you can consider this change (or some 
> variation of it).
> 
> Nacho Soto
> ___
> 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] [Accepted with revisions] SE-0187 “Introduce Sequence.filterMap(_:)”

2017-12-23 Thread Cheyo Jose Jimenez via swift-evolution
+1 for .mapCompacting 

> On Dec 21, 2017, at 8:49 PM, Erica Sadun via swift-evolution 
>  wrote:
> 
> 
> 
>>> On Dec 19, 2017, at 4:42 PM, Dave Abrahams via swift-evolution 
>>>  wrote:
>>> 
>>> 
>>> 
>>> On Dec 19, 2017, at 2:28 PM, Xiaodi Wu via swift-evolution 
>>>  wrote:
>>> 
>>> I disagree. Let’s not reopen what is settled. “Compact” can be a noun just 
>>> as “map” and “filter” can; as long as there are no in-place variants, there 
>>> can be no ambiguity.
>>> On Tue, Dec 19, 2017 at 17:11 Brent Royal-Gordon via swift-evolution 
>>>  wrote:
> On Dec 19, 2017, at 8:56 AM, John McCall  wrote:
> 
> Therefore, SE-0187 is accepted, with the revision that the new name be 
> Sequence.compactMap(_:), and with the agreement that we will add 
> Sequence.compact() when it is possible to do so.
 
 
 I like `compact` as the basis for the name, but I hope the core team will 
 consider whether the eventual nil-removal method should be called 
 `compacting()`, and whether therefore this method should be called 
 `compactingMap(_:)`. Prior art on the name `compact()` does exist, but I 
 don't think it's strong enough to justify deviating from the API 
 Guidelines.
 
 I don't think we need a full review on this tiny issue; five minutes of 
 the core team's time should more than suffice.
>> 
>> I agree with Brent. IMO we're firmly outside the domain of established 
>> terms-of-art here (Ruby notwithstanding). 
> 
> I lean slightly towards "but they already have been through this", but given 
> that the core term is "compact" and it is secondary to map, then I think 
> `mapCompacting` is superior: 
> 
> * It mirrors the process better (apply function, then decide whether to 
> include or exclude the result)
> * It prefers `compacting` as Brent points out, supporting the Swift API 
> Guidelines
> * It uses the term of art `map` consistently with this preferred term.
> * It places the two names closer together in autocomplete
> 
> -- E, hiding the bikeshed paintbrush behind her back
> ___
> 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] [Review] SE 0192 - Non-Exhaustive Enums

2017-12-23 Thread Cheyo Jose Jimenez via swift-evolution


> On Dec 23, 2017, at 3:19 AM, Thomas Roughton via swift-evolution 
>  wrote:
> 
> Looking at the feedback to this proposal, it looks like a common thread is 
> people wanting to make sure they’re notified when new cases are introduced 
> (the ‘future’ keyword’). However, if I’m understanding correctly, the 
> resistance to adding such a keyword is that it becomes complicated when 
> there’s e.g. both a ‘future’ and ‘default’ case, with two different sets of 
> behaviour. I missed the earlier discussion around this proposal so forgive me 
> if this is a concept that’s been brought up before.
> 
> A possible alternative would be to build on that concept, but place the 
> weight on the ‘switch’ statement. I’d propose something like the following 
> for a non-exhaustive enum that currently has cases ‘a’ and ‘b’.
> 
> @complete switch nonExhaustiveEnum {
>case a:
>print(“a”)
>case b:
>print(“b”)
>future:
>break
> }

The `final switch` mentioned in the proposal seems like a good solution to this 
problem. 
http://dlang.org/statement.html#FinalSwitchStatement


> 
> where the semantics would be that in a @complete switch statement, all known 
> cases must be explicitly switched. The ‘future’ case would have the same 
> run-time semantics as a default case for a non-@complete switch (I’m sticking 
> with the ‘future’ name here since I think it’s clearer, but continuing to use 
> ‘default’ would also work). If the external library is modified and the user 
> code is then recompiled, Swift would error at compile time saying that there 
> were unhandled cases.
> 
> Obviously, this still requires adding keywords to the language and some 
> degree of complexity, but does mean the behaviour change is isolated to a 
> fairly simple compile-time check.
> 
> Thomas
> ___
> 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] [Review] SE 0192 - Non-Exhaustive Enums

2017-12-23 Thread Dave DeLong via swift-evolution
Continuing on this vein, there is another huge reason this proposal is 
incomplete and won’t solve the problem.

This proposal, as I outlined previously, is all about binary compatibility and 
functional resilience in the face of changing libraries. However, it falls 
woefully short by only considering the binary implications of changing enums.

The problem of binary compatibility extends *far* beyond the mutation of enums 
between library versions. By only considering the “enum problem”, we are 
ignoring a much larger and worse problem that will be even easier for libraries 
to succumb to. It’s easy as a library author to inadvertently rename a method 
or change the type of a parameter, or add a parameter, or change the return 
type, or change the implementation semantics, or remove a type, or remove a 
function, in such a way that a linking app cannot handle. This is why the 
burden of binary compatibility rightfully rests on library authors, and not app 
authors. 

The thing that changes has the responsibility to maintain compatibility for the 
thing that hasn’t changed.

We should absolutely not implement this proposal; it only addresses a single 
portion of a very large problem. Instead, we should figure out what the broader 
binary compatibility story is. If we can answer *that* and provide the 
necessary features to address it, then enum resilience will naturally fall out 
of it. Focusing on the enum problem is focusing on the wrong problem.

Dave

> On Dec 21, 2017, at 11:02 AM, Dave DeLong  wrote:
> 
> I realized further why we should not implement this proposal: It forces the 
> problem of binary compatibility on the app developer, when experience has 
> shown us that problem is better handled by the libraries.
> 
> Binary Compatibility
> 
> “Binary compatibility” is the notion that, even if the libraries you link 
> against change, your app will still behave as it did when it was first 
> compiled. For Swift apps these days, we don’t really have this problem, 
> *yet*. We do have the problem of “binary compatibility” with Apple-provided 
> frameworks, but those are all written in Objective-C, and so the question of 
> “Swift” binary compatibility is still up-in-the-air.
> 
> Post-ABI stability, we still won’t have much issue with swift binary 
> compatibility on Apple platforms, because there isn’t a mechanism to ship a 
> framework to your users independently of an app update. So from the app POV, 
> none of this will be a problem for Apple platform developers.
> 
> It will be a problem for non-Apple platform developers. As a simple example, 
> let’s say I write a web app in Swift, and deploy it to a server that has some 
> built-in Swift-on-the-server libraries. Here, my Swift app is decoupled from 
> the libraries, and either one can update independently of each other. If the 
> server owner decides to update from Swift 6 to Swift 6.1, that’s cool. But my 
> web app should continue to run and behave *as if* the server were still 
> running Swift 6, because it has not been re-compiled to use Swift 6.1 
> features.
> 
> This is the situation today on Apple platforms. Every app deployed to an 
> Apple device includes a little piece of information in the executable file 
> indicating which SDK was used to compile the app. At runtime, the system 
> frameworks read this value and then alter their behavior accordingly. This is 
> why apps written against the iOS 9 SDK continue to work on iOS 11 devices; 
> UIKit and friends are altering their behavior to provide iOS 9 semantics. 
> 
> This is “binary compatibility”: the binary (your app) continues to be 
> compatible with the dynamically linked frameworks present on the system, even 
> though those frameworks may change.
> 
> When you have a setup where the frameworks do NOT provide binary 
> compatibility, you end up in DLL Hell [1]. This is the same frustrating 
> scenario when you’re in when you’re doing stuff with homebrew and find that 
> this package you want has multiple dependencies, but these dependencies want 
> different versions of the same library. [2]
> 
> Exhaustive Enums
> 
> All of the discussion around exhaustive enums has been from the point-of-view 
> of “what should the behavior be when the libraries change”. Thinking back, 
> I’m actually surprised this is a question at all, because Apple answered this 
> *years* ago: THE BEHAVIOR SHOULD REMAIN UNCHANGED. It is up to the library 
> authors to ensure that they’re doing what the compiled-and-unchanging 
> application is expecting them to do.
> 
> This discussion around exhaustive enums is basically saying “can we force the 
> developers to deal with binary incompatibility?”. We absolutely should not. 
> There are far more app developers than library developers, and it would be a 
> massively wasteful expenditure of engineering effort to force each and every 
> app developer to deal with binary incompatibility, when the library can do it 
> for them. That is 

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

2017-12-23 Thread Jonathan Hull via swift-evolution

> On Dec 21, 2017, at 11:07 AM, Jordan Rose  wrote:
> 
> Thanks for your comments, Jon. Responses inline.
> 
>> On Dec 20, 2017, at 12:46, Jonathan Hull > > wrote:
>> 
>> 
>>> On Dec 19, 2017, at 2:58 PM, Ted Kremenek via swift-evolution 
>>> > wrote:
>>> When reviewing a proposal, here are some questions to consider:
>>> 
>>> What is your evaluation of the proposal?
>>> 
>> Strong -1 as is.
>> 
>> I think I would support having an explicit ‘futureCase’ which is different 
>> from ‘default’.  Requiring default is asking for bugs.  With a separate 
>> ‘futureCase’, we would still get a compile-time error when all of the 
>> current cases aren’t handled.  Note that ‘ futureCase’ is also different 
>> than ‘default’ in that it wouldn’t have to go at the bottom.  It would only 
>> be triggered when the value isn’t one of the values which was known at 
>> compile time.  We should also bike shed the name of ‘futureCase’ to come up 
>> with something that might allow us to make other types of extendable enums…. 
>>  Maybe something like ‘unknownCase’ or ‘unexpectedCase’.
>> 
>> As for the issue of testing, we could add (later) a universally unexpected 
>> case that non-exhaustive enums can be set to for testing. I am not convinced 
>> that this is actually a big enough issue to warrant that though. Forcing 
>> ‘default’ is a much larger real-world problem, IMO (and this use of 
>> ‘default’ is just as untestable).
> 
> Both of these are discussed in "Alternatives considered", and they have flaws 
> that led me to leave them out of the proposal. Do you have any ideas on how 
> to improve on that?

What are the flaws?  I saw that the ‘Future’ case can’t be tested… but using 
‘default’ is just as untestable in the same way.  Others have given lots of 
examples where it will actually be used.

I think we should reframe it so that instead of talking about exhaustive vs. 
non-exhaustive, all switches need to be exhaustive… but switches over these 
enums need to handle unexpected cases to be considered exhaustive.

I know it is marked as an “alternative”, but it seems clear to me that having 
an ‘unexpected’ case (which only matches cases not known at compile time) is 
the clear answer here.  Something like 75% of  responses have mentioned it.


> 
>> 
>> I also dislike the name @exhaustive because I think it will cause confusion 
>> (i.e. “Of course my Enum is exhaustive”).  I think we should just have 
>> @fixed for both enums and structs. The word fixed has the connotation that 
>> it shouldn’t change.
> 
> I don't think anybody loves "exhaustive", but using the same attribute for 
> enums and structs isn't really appropriate, as discussed in my response to 
> Karl yesterday 
> .
>  I'm not opposed to a better name if we can gravitate towards one, though.

I really like @frozen.  It has a much clearer connotation of what it means, and 
can be used for structs too.

Thanks,
Jon

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


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

2017-12-23 Thread Thomas Roughton via swift-evolution
Looking at the feedback to this proposal, it looks like a common thread is 
people wanting to make sure they’re notified when new cases are introduced (the 
‘future’ keyword’). However, if I’m understanding correctly, the resistance to 
adding such a keyword is that it becomes complicated when there’s e.g. both a 
‘future’ and ‘default’ case, with two different sets of behaviour. I missed the 
earlier discussion around this proposal so forgive me if this is a concept 
that’s been brought up before.

A possible alternative would be to build on that concept, but place the weight 
on the ‘switch’ statement. I’d propose something like the following for a 
non-exhaustive enum that currently has cases ‘a’ and ‘b’.

@complete switch nonExhaustiveEnum {
case a:
print(“a”)
case b:
print(“b”)
future:
break
}

where the semantics would be that in a @complete switch statement, all known 
cases must be explicitly switched. The ‘future’ case would have the same 
run-time semantics as a default case for a non-@complete switch (I’m sticking 
with the ‘future’ name here since I think it’s clearer, but continuing to use 
‘default’ would also work). If the external library is modified and the user 
code is then recompiled, Swift would error at compile time saying that there 
were unhandled cases.

Obviously, this still requires adding keywords to the language and some degree 
of complexity, but does mean the behaviour change is isolated to a fairly 
simple compile-time check.

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