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

2018-01-05 Thread Jon Shier via swift-evolution
At this point I think it might be useful to outline how binary compatibility 
works for Objective-C on Apple platforms right now. As an app developer I’m not 
intimately familiar with what happens when you run an app compiled with the iOS 
10 SDK on iOS 11. Are there just runtime checks to call old code paths or 
something else? The more this thread goes on the more confused I get about why 
Swift would have this issue while it doesn’t appear to be one for Obj-C. If an 
enum adds a case now, I don’t have to care until I recompile using the new SDK. 
Is the intention for Swift to be different in this regard?



Jon Shier

> On Jan 5, 2018, at 6:41 PM, Jordan Rose via swift-evolution 
>  wrote:
> 
> 
> 
>> On Jan 3, 2018, at 00:54, Jason Merchant via swift-evolution 
>>  wrote:
>> 
>> Is it hard to imagine that most everyone can get what they want and keep the 
>> syntax clean and streamlined at the same time? Without any "@" signs or 
>> other compiler hints?
> 
> For what it's worth, the original version of the proposal started with a 
> modifier (a context-sensitive keyword, like 'final'), but the core team felt 
> that there were a lot of modifiers in the language already, and this didn't 
> meet the bar.
> 
> 
>>> "Rather, we are how to enable the vendor of a nonexhaustive enum to add new 
>>> cases without breaking binaries compiled against previous versions"
>> 
>> When an enum changes, and the change causes the code to break, the user can 
>> be presented with migration options from an automated IDE tool. In what 
>> specific way does this not solve the issue about having to upgrade your code 
>> when using someone else's code library? This very notion implies your 
>> disgruntled about doing work when things are upgraded, is that really what 
>> this fuss is all about?
>> 
>> A well written language interpreter and auto-tooling IDE would not need 
>> hints embedded in the code syntax itself. Migration hints from version to 
>> version should not be a part of either the past or future version of the 
>> code library.
> 
> Thanks for bringing this up! Unfortunately, it falls down in practice, 
> because if there's a new enum case, it's unclear what you want to do with it. 
> If you're handling errors, it's not obvious that the way you've handled any 
> of the other errors is appropriate. In the (admittedly controversial) 
> SKPaymentTransactionState case, none of the existing code would be 
> appropriate to handle the newly-introduced "deferred" case, and nor could 
> StoreKit provide "template" code that would be appropriate to the client app.
> 
> 
> In any case, though, the key point on this particular quoted sentence is 
> "without breaking binaries". Any such change must be valid without 
> recompilation, and indeed without any intervention from the developer or an 
> IDE, because that's what happens when the user updates their OS.
> 
> Jordan
> 
> 
> 
>> 
>> ...
>> 
>> I don't expect the community to agree on language grammar, but the common 
>> sense here on how to achieve the intended goals seems to be out of wack.
>> 
>> If someone can present a clear logical statement as to how an automated 
>> migration tool behind the scenes in the IDE to handle all your versioning 
>> worries, does not make this whole discussion about adding more convoluted 
>> syntax additions irrelevant, I'd love to hear it.
>> 
>> ___
>> 
>> Sincerely,
>> Jason
>> 
>> 
>> 
>> 
>> 
>> 
>>> On Tue, Jan 2, 2018 at 12:36 PM, Xiaodi Wu  wrote:
 On Tue, Jan 2, 2018 at 12:11 PM, Jason Merchant via swift-evolution 
  wrote:
>>> 
 I think this whole thing has been unnecessarily convoluted. As a result, 
 the majority of the replies are rabbit holes.
 
 In my opinion, the true root of the concept in question is as follows:
 
 A list of something is desired:
 1 - Pancake
 2 - Waffle
 3 - Juice
 
 Developer wishes to be able to:
 A) Add new things to the list of choices in the future as they come up 
 with new ideas
 B) Sometimes select one of the choices to be chosen as the normal choice 
 if no choice is made by the user
 
 A and B are separate desires. In some circumstances a developer may want 
 to add a new choice and make it the normal choice when there was no normal 
 choice was clarified before.
>>> 
>>> I don't think this is an accurate summary of the problem being tackled 
>>> here. Rather, we are how to enable the vendor of a nonexhaustive enum to 
>>> add new cases without breaking binaries compiled against previous versions. 
>>> There is little here to do with what a "default" should be. Indeed, it is 
>>> an explicit design decision of Swift not to support types having an 
>>> implicit default value.
>>>  
 
 
 Part 2:
 
 After this simple desire is clear, there should be two 

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

2018-01-05 Thread Jordan Rose via swift-evolution


> On Jan 3, 2018, at 00:54, Jason Merchant via swift-evolution 
>  wrote:
> 
> Is it hard to imagine that most everyone can get what they want and keep the 
> syntax clean and streamlined at the same time? Without any "@" signs or other 
> compiler hints?

For what it's worth, the original version of the proposal started with a 
modifier (a context-sensitive keyword, like 'final'), but the core team felt 
that there were a lot of modifiers in the language already, and this didn't 
meet the bar.


> "Rather, we are how to enable the vendor of a nonexhaustive enum to add new 
> cases without breaking binaries compiled against previous versions"
> 
> When an enum changes, and the change causes the code to break, the user can 
> be presented with migration options from an automated IDE tool. In what 
> specific way does this not solve the issue about having to upgrade your code 
> when using someone else's code library? This very notion implies your 
> disgruntled about doing work when things are upgraded, is that really what 
> this fuss is all about?
> 
> A well written language interpreter and auto-tooling IDE would not need hints 
> embedded in the code syntax itself. Migration hints from version to version 
> should not be a part of either the past or future version of the code library.

Thanks for bringing this up! Unfortunately, it falls down in practice, because 
if there's a new enum case, it's unclear what you want to do with it. If you're 
handling errors, it's not obvious that the way you've handled any of the other 
errors is appropriate. In the (admittedly controversial) 
SKPaymentTransactionState case, none of the existing code would be appropriate 
to handle the newly-introduced "deferred" case, and nor could StoreKit provide 
"template" code that would be appropriate to the client app.


In any case, though, the key point on this particular quoted sentence is 
"without breaking binaries". Any such change must be valid without 
recompilation, and indeed without any intervention from the developer or an 
IDE, because that's what happens when the user updates their OS.

Jordan



> 
> ...
> 
> I don't expect the community to agree on language grammar, but the common 
> sense here on how to achieve the intended goals seems to be out of wack.
> 
> If someone can present a clear logical statement as to how an automated 
> migration tool behind the scenes in the IDE to handle all your versioning 
> worries, does not make this whole discussion about adding more convoluted 
> syntax additions irrelevant, I'd love to hear it.
> 
> ___
> 
> Sincerely,
> Jason
> 
> 
> 
> 
> 
> 
> On Tue, Jan 2, 2018 at 12:36 PM, Xiaodi Wu  > wrote:
> On Tue, Jan 2, 2018 at 12:11 PM, Jason Merchant via swift-evolution 
> > wrote:
> I think this whole thing has been unnecessarily convoluted. As a result, the 
> majority of the replies are rabbit holes.
> 
> In my opinion, the true root of the concept in question is as follows:
> 
> A list of something is desired:
> 1 - Pancake
> 2 - Waffle
> 3 - Juice
> 
> Developer wishes to be able to:
> A) Add new things to the list of choices in the future as they come up with 
> new ideas
> B) Sometimes select one of the choices to be chosen as the normal choice if 
> no choice is made by the user
> 
> A and B are separate desires. In some circumstances a developer may want to 
> add a new choice and make it the normal choice when there was no normal 
> choice was clarified before.
> 
> I don't think this is an accurate summary of the problem being tackled here. 
> Rather, we are how to enable the vendor of a nonexhaustive enum to add new 
> cases without breaking binaries compiled against previous versions. There is 
> little here to do with what a "default" should be. Indeed, it is an explicit 
> design decision of Swift not to support types having an implicit default 
> value.
>  
> 
> 
> Part 2:
> 
> After this simple desire is clear, there should be two discussions:
> A) In a text only coding language, what would we like the syntax to look 
> like? (Without regard to past-bias. What should it really be, forget what 
> mistaken design choices were made in Swift in the past)
> B) How do we approach making this happen behind the scenes?
> 
> Bonus: Given that some of us have changed our approach to programming 
> significantly beyond text based coding, and into more dynamic mediums of 
> programming in other niches, and even here and there in Xcode - I would 
> recommend considering how the IDE would show a modern version of this 
> concept. I feel too often that Swift design syntax has a lack of awareness 
> between the distinctions of what the IDE should do, as opposed to what the 
> syntax of the language should be, and what should be handled behind the 
> scenes by automated tooling.
> 
> 

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] [Review] SE 0192 - Non-Exhaustive Enums

2018-01-05 Thread Jonathan Hull via swift-evolution
Oh, I see… the case would silently change from unexpected to default if they 
were both included.  Hmm.  I will have to think on this more.

Thanks,
Jon

> On Jan 5, 2018, at 3:17 PM, Jordan Rose  wrote:
> 
> 
> 
>> On Jan 5, 2018, at 00:11, Jonathan Hull via swift-evolution 
>> > wrote:
>> 
>>> 
>>> On Jan 4, 2018, at 11:02 PM, Xiaodi Wu >> > wrote:
>>> 
>>> 
>>> On Fri, Jan 5, 2018 at 01:56 Jonathan Hull >> > wrote:
 On Jan 4, 2018, at 10:31 PM, Xiaodi Wu via swift-evolution 
 > wrote:
>>> 
 
 On Fri, Jan 5, 2018 at 00:21 Cheyo Jimenez > wrote:
>>> 
 
 On Jan 4, 2018, at 4:37 PM, Xiaodi Wu > wrote:
 
>>> 
> On Thu, Jan 4, 2018 at 19:29 Cheyo J. Jimenez  > wrote:
> 
> We seem to agree that, by virtue of not supporting use in a pattern and 
> being placed at the end, the feature is a flavor of default. I’m still 
> not sure I understand why you believe it should not be a flavor of 
> default going forward.
> 
>> 
>> You still haven’t answered my question, though—what’s the use case for 
>> the feature you propose?
> 
> My use case would be distinguishing between compile time known cases vs 
> “future only” cases (or unknown cases).
> 
> I understand that the feature you propose would allow you to make such a 
> distinction, but again, what is your use case for doing so?
>>> 
 Breaking out early by checking unknown cases first. I admit this is not 
 deal breaker, just a different style I’d like to see supported in the 
 future. 
>>> 
 
 I'm still not sure I understand. How can the machine know that it's 
 dealing with an unknown case without first checking if it matches any 
 known case?
>>> 
>>> 
>>> I had the same thought as Cheyo.  It isn’t a deal breaker… I like the 
>>> compromise, but I would prefer it trigger only on an actual unknown case 
>>> (as opposed to acting like default). I like to break failure cases out at 
>>> the top when possible. I don’t see any good reason not to support that 
>>> style.
>>> 
>>> To answer your question, in the naive sense, it basically is the same 
>>> question as asking if it is a known case (and then taking the inverse). 
>>> That doesn’t mean actually checking each case separately though. For 
>>> example, if the enum cases are internally represented as an unsigned 
>>> integer, and they are all together in a block, the compiler could simply 
>>> check that it is greater than the max known value. You could probably even 
>>> do a bit mask comparison in some cases...
>>> 
>>> These are obvious optimizations, but why does this require new syntax?
>> 
>> I am not sure I understand what you are asking. There isn’t additional 
>> syntax.  We are just arguing over the name + behavior of ‘unexpected:’.  You 
>> want it to behave like ‘default’ and I am saying that stops the use case I 
>> mention above.
>> 
>> 
>>> What do you gain from writing the unknown case first?
>> I know where to look for the failure cases.  I also tend put a bunch of 
>> guard statements near the beginning of a function.  It is just a programming 
>> style.
>> 
>> With my behavior of ‘unexpected:’ you can put it wherever you want.  Why 
>> limit that by forcing it to go at the end?
>> 
>>> Isn't this basically the same thing as asking for the ability to write the 
>>> default case first, a frequently suggested and rejected syntax addition?
>> 
>> No.  I don’t think I have ever heard that asked for, but putting default in 
>> a different place has a different meaning.  The way I read a switch 
>> statement anyway is that it tries each case until it find one that matches.  
>> Default matches everything, so it has to go at the end (since it will always 
>> match and nothing afterwards will be tried).
>> 
>> Having ‘unexpected:’ also match known/expected cases is problematic as a 
>> mental model.  I think that is just an artifact of the original proposal 
>> using default.  There is no reason 'unexpected:’ should have to handle known 
>> cases as well… let’s just have it trigger on unexpected ones.
> 
> I'm going to repeat this from my reply to Cheyo earlier: I really, really 
> don't want recompiling code against a different version of the library to 
> pick a different case than it did before.
> 
> (This might be a weak argument since overload resolution, protocol 
> conformance checking, etc can end up picking a different declaration than it 
> did before. But I would hope that the overloads or alternate protocol 
> witnesses at least "do the same thing" in normal situations, if 

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

2018-01-05 Thread Jordan Rose via swift-evolution


> On Jan 5, 2018, at 00:11, Jonathan Hull via swift-evolution 
>  wrote:
> 
>> 
>> On Jan 4, 2018, at 11:02 PM, Xiaodi Wu > > wrote:
>> 
>> 
>> On Fri, Jan 5, 2018 at 01:56 Jonathan Hull > > wrote:
>>> On Jan 4, 2018, at 10:31 PM, Xiaodi Wu via swift-evolution 
>>> > wrote:
>> 
>>> 
>>> On Fri, Jan 5, 2018 at 00:21 Cheyo Jimenez >> > wrote:
>> 
>>> 
>>> On Jan 4, 2018, at 4:37 PM, Xiaodi Wu >> > wrote:
>>> 
>> 
 On Thu, Jan 4, 2018 at 19:29 Cheyo J. Jimenez > wrote:
 
 We seem to agree that, by virtue of not supporting use in a pattern and 
 being placed at the end, the feature is a flavor of default. I’m still not 
 sure I understand why you believe it should not be a flavor of default 
 going forward.
 
> 
> You still haven’t answered my question, though—what’s the use case for 
> the feature you propose?
 
 My use case would be distinguishing between compile time known cases vs 
 “future only” cases (or unknown cases).
 
 I understand that the feature you propose would allow you to make such a 
 distinction, but again, what is your use case for doing so?
>> 
>>> Breaking out early by checking unknown cases first. I admit this is not 
>>> deal breaker, just a different style I’d like to see supported in the 
>>> future. 
>> 
>>> 
>>> I'm still not sure I understand. How can the machine know that it's dealing 
>>> with an unknown case without first checking if it matches any known case?
>> 
>> 
>> I had the same thought as Cheyo.  It isn’t a deal breaker… I like the 
>> compromise, but I would prefer it trigger only on an actual unknown case (as 
>> opposed to acting like default). I like to break failure cases out at the 
>> top when possible. I don’t see any good reason not to support that style.
>> 
>> To answer your question, in the naive sense, it basically is the same 
>> question as asking if it is a known case (and then taking the inverse). That 
>> doesn’t mean actually checking each case separately though. For example, if 
>> the enum cases are internally represented as an unsigned integer, and they 
>> are all together in a block, the compiler could simply check that it is 
>> greater than the max known value. You could probably even do a bit mask 
>> comparison in some cases...
>> 
>> These are obvious optimizations, but why does this require new syntax?
> 
> I am not sure I understand what you are asking. There isn’t additional 
> syntax.  We are just arguing over the name + behavior of ‘unexpected:’.  You 
> want it to behave like ‘default’ and I am saying that stops the use case I 
> mention above.
> 
> 
>> What do you gain from writing the unknown case first?
> I know where to look for the failure cases.  I also tend put a bunch of guard 
> statements near the beginning of a function.  It is just a programming style.
> 
> With my behavior of ‘unexpected:’ you can put it wherever you want.  Why 
> limit that by forcing it to go at the end?
> 
>> Isn't this basically the same thing as asking for the ability to write the 
>> default case first, a frequently suggested and rejected syntax addition?
> 
> No.  I don’t think I have ever heard that asked for, but putting default in a 
> different place has a different meaning.  The way I read a switch statement 
> anyway is that it tries each case until it find one that matches.  Default 
> matches everything, so it has to go at the end (since it will always match 
> and nothing afterwards will be tried).
> 
> Having ‘unexpected:’ also match known/expected cases is problematic as a 
> mental model.  I think that is just an artifact of the original proposal 
> using default.  There is no reason 'unexpected:’ should have to handle known 
> cases as well… let’s just have it trigger on unexpected ones.

I'm going to repeat this from my reply to Cheyo earlier: I really, really don't 
want recompiling code against a different version of the library to pick a 
different case than it did before.

(This might be a weak argument since overload resolution, protocol conformance 
checking, etc can end up picking a different declaration than it did before. 
But I would hope that the overloads or alternate protocol witnesses at least 
"do the same thing" in normal situations, if possibly more efficiently. I 
wouldn't expect that for `unknown case` vs. `default` if you actually had both 
of them.)


The reason `unknown case` has to match known cases is, again, for source 
compatibility. If the compiler only produces a warning, rather than an error, 
when you're missing a case, it has to do something if that case comes up. The 
most reasonable thing for it to do (in 

Re: [swift-evolution] Questions about non-exhaustive enums

2018-01-05 Thread Lance Parker via swift-evolution
This is the same issue as when a library maintainer changes a class from open 
to closed.

> On Jan 5, 2018, at 10:54 AM, Ignacio Soto via swift-evolution 
>  wrote:
> 
> I love the revision to the proposal 
> , but I have a couple of 
> remaining questions that don't seem to be addressed in the doc and I'm 
> curious about:
> What happens if a library maintainer adds a new case to a @frozen enum?
> What happens if a library maintainer changes an enum from @frozen to 
> non-frozen?
> Thanks!
> 
> 
> -- 
> Ignacio 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


[swift-evolution] Questions about non-exhaustive enums

2018-01-05 Thread Ignacio Soto via swift-evolution
I love the revision to the proposal
, but I have a couple of
remaining questions that don't seem to be addressed in the doc and I'm
curious about:

   - What happens if a library maintainer adds a new case to a *@frozen*
   enum?
   - What happens if a library maintainer changes an enum from *@frozen* to
   non-frozen?

Thanks!


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

2018-01-05 Thread Cheyo J. Jimenez via swift-evolution

> On Jan 5, 2018, at 4:42 AM, Xiaodi Wu  wrote:
> 
> 
> On Fri, Jan 5, 2018 at 03:11 Jonathan Hull  > wrote:
>> On Jan 4, 2018, at 11:02 PM, Xiaodi Wu > > wrote:
>> 
>> 
>> On Fri, Jan 5, 2018 at 01:56 Jonathan Hull > > wrote:
>>> On Jan 4, 2018, at 10:31 PM, Xiaodi Wu via swift-evolution 
>>> > wrote:
>> 
>>> 
>>> On Fri, Jan 5, 2018 at 00:21 Cheyo Jimenez >> > wrote:
>> 
>>> 
>>> On Jan 4, 2018, at 4:37 PM, Xiaodi Wu >> > wrote:
>>> 
>> 
 On Thu, Jan 4, 2018 at 19:29 Cheyo J. Jimenez > wrote:
 
 We seem to agree that, by virtue of not supporting use in a pattern and 
 being placed at the end, the feature is a flavor of default. I’m still not 
 sure I understand why you believe it should not be a flavor of default 
 going forward.
 
> 
> You still haven’t answered my question, though—what’s the use case for 
> the feature you propose?
 
 My use case would be distinguishing between compile time known cases vs 
 “future only” cases (or unknown cases).
 
 I understand that the feature you propose would allow you to make such a 
 distinction, but again, what is your use case for doing so?
>> 
>>> Breaking out early by checking unknown cases first. I admit this is not 
>>> deal breaker, just a different style I’d like to see supported in the 
>>> future. 
>> 
>>> 
>>> I'm still not sure I understand. How can the machine know that it's dealing 
>>> with an unknown case without first checking if it matches any known case?
>> 
>> 
>> I had the same thought as Cheyo.  It isn’t a deal breaker… I like the 
>> compromise, but I would prefer it trigger only on an actual unknown case (as 
>> opposed to acting like default). I like to break failure cases out at the 
>> top when possible. I don’t see any good reason not to support that style.
>> 
>> To answer your question, in the naive sense, it basically is the same 
>> question as asking if it is a known case (and then taking the inverse). That 
>> doesn’t mean actually checking each case separately though. For example, if 
>> the enum cases are internally represented as an unsigned integer, and they 
>> are all together in a block, the compiler could simply check that it is 
>> greater than the max known value. You could probably even do a bit mask 
>> comparison in some cases...
>> 
>> These are obvious optimizations, but why does this require new syntax?
> 
> I am not sure I understand what you are asking. There isn’t additional 
> syntax.  We are just arguing over the name + behavior of ‘unexpected:’.  You 
> want it to behave like ‘default’ and I am saying that stops the use case I 
> mention above.
> 
> Cheyo said he wants “unexpected case” to work in pattern matching, as well as 
> a new “case *” that is distinct from “case _”. This is additional syntax. 
> When asked what the use case was for these suggestions, he said he wants to 
> distinguish between known and unknown cases at the beginning of the switch.
> 
> 
> 
>> What do you gain from writing the unknown case first?
> 
> I know where to look for the failure cases.  I also tend put a bunch of guard 
> statements near the beginning of a function.  It is just a programming style.
> 
> With my behavior of ‘unexpected:’ you can put it wherever you want.  Why 
> limit that by forcing it to go at the end?
> 
> As pointed out earlier (by one of the core team members, I think), meaningful 
> resilience would mean that the unexpected or unknown case should have useful 
> work executed at runtime; the intention is that the user *shouldn’t* be 
> treating it as a runtime “failure case,” as it effectively makes adding an 
> enum case a change that is incompatible with existing binaries (i.e., not 
> terribly resilient).
> 
> As you and I seem to agree, reaching an unexpected case requires at least 
> notionally considering which cases are expected in the first place. This is 
> the dictionary definition of a default, and Swift usage is to put the default 
> case at the end of a switch statement. Adding new syntax as Cheyo suggests to 
> enable putting it elsewhere, merely for “style,” doesn’t seem to pass the bar 
> for new syntax, nor is it consistent with existing Swift usage.

I agree with the new syntax suggestion is premature. I would hope that the 
proposed runtime "Deriving collections of enum cases” 
 function also has a 
compile time version which we can then use to match all the known cases at 
compile time. I am happy with SE 0192 as it stands now. 


> 
>> Isn't this basically the same thing as asking for the ability 

Re: [swift-evolution] why cant you initialize BinaryFloatingPoint from BinaryInteger?

2018-01-05 Thread Nate Cook via swift-evolution
Right, SE-0067 included that initializer with the caveat that implementation 
wouldn't be possible until the integer protocols were revised. As far as I can 
see, that makes this a fix that wouldn't need further SE discussion. (The 
generic init(exactly:) needs an implementation, too.)

https://github.com/apple/swift-evolution/blob/master/proposals/0067-floating-point-protocols.md

Nate

> On Jan 1, 2018, at 7:01 PM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> This would be a good addition to the BinaryFloatingPoint protocol. It's not 
> difficult to implement; it's not present (afaict) simply because 
> BinaryFloatingPoint was designed before BinaryInteger existed.
> 
> 
>> On Mon, Jan 1, 2018 at 3:58 PM, Kelvin Ma via swift-evolution 
>>  wrote:
>> title says it all,, this is kind of annoying when writing some generic 
>> FloatingPoint code where both the integral and floating parameters are 
>> unfixed.
>> 
>> ___
>> 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-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] DynamicMemberLookup proposal: status update

2018-01-05 Thread Ben Rimmington via swift-evolution
Have you seen John Holdsworth's experiments?


-- Ben

> On 4 Jan 2018, at 20:52, Chris Lattner wrote:
> 
> Hi everyone,
> 
> With the holidays and many other things behind us, the core team had a chance 
> to talk about python interop + the dynamic member lookup proposal recently.
> 
> Here’s where things stand: we specifically discussed whether a 
> counter-proposal of using “automatically generated wrappers” or “foreign 
> classes” to solve the problem would be better.  After discussion, the 
> conclusion is no: the best approach appears to be 
> DynamicMemberLookup/DynamicCallable or something similar in spirit to them.  
> As such, I’ll be dusting off the proposal and we’ll eventually run it.
> 
> For transparency, I’m attaching the analysis below of what a wrapper facility 
> could look like, and why it doesn’t work very well for Python interop.  I 
> appologize in advance that this is sort of train-of-thought and not a well 
> written doc. 
> 
> That said, it would be really great to get tighter integration between Swift 
> and SwiftPM for other purposes!  I don’t have time to push this forward in 
> the short term though, but if someone was interested in pushing it forward, 
> many people would love to see it discussed seriously.
> 
> -Chris

___
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

2018-01-05 Thread Xiaodi Wu via swift-evolution
On Fri, Jan 5, 2018 at 03:11 Jonathan Hull  wrote:

> On Jan 4, 2018, at 11:02 PM, Xiaodi Wu  wrote:
>
>
> On Fri, Jan 5, 2018 at 01:56 Jonathan Hull  wrote:
>
>> On Jan 4, 2018, at 10:31 PM, Xiaodi Wu via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>>
>> On Fri, Jan 5, 2018 at 00:21 Cheyo Jimenez  wrote:
>>
>>
>>> On Jan 4, 2018, at 4:37 PM, Xiaodi Wu  wrote:
>>>
>>> On Thu, Jan 4, 2018 at 19:29 Cheyo J. Jimenez 
>>> wrote:
>>>
>>> We seem to agree that, by virtue of not supporting use in a pattern and
>>> being placed at the end, the feature is a flavor of default. I’m still not
>>> sure I understand why you believe it should not be a flavor of default
>>> going forward.
>>>
>>>
 You still haven’t answered my question, though—what’s the use case for
 the feature you propose?


 My use case would be distinguishing between compile time known cases vs
 “future only” cases (or unknown cases).

>>>
>>> I understand that the feature you propose would allow you to make such a
>>> distinction, but again, what is your use case for doing so?
>>>
>>> Breaking out early by checking unknown cases first. I admit this is not
>>> deal breaker, just a different style I’d like to see supported in the
>>> future.
>>>
>>
>> I'm still not sure I understand. How can the machine know that it's
>> dealing with an unknown case without first checking if it matches any known
>> case?
>>
>>
>> I had the same thought as Cheyo.  It isn’t a deal breaker… I like the
>> compromise, but I would prefer it trigger only on an actual unknown case
>> (as opposed to acting like default). I like to break failure cases out at
>> the top when possible. I don’t see any good reason not to support that
>> style.
>>
>> To answer your question, in the naive sense, it basically is the same
>> question as asking if it is a known case (and then taking the inverse).
>> That doesn’t mean actually checking each case separately though. For
>> example, if the enum cases are internally represented as an unsigned
>> integer, and they are all together in a block, the compiler could simply
>> check that it is greater than the max known value. You could probably even
>> do a bit mask comparison in some cases...
>>
>
> These are obvious optimizations, but why does this require new syntax?
>
>
> I am not sure I understand what you are asking. There isn’t additional
> syntax.  We are just arguing over the name + behavior of ‘unexpected:’.
> You want it to behave like ‘default’ and I am saying that stops the use
> case I mention above.
>

Cheyo said he wants “unexpected case” to work in pattern matching, as well
as a new “case *” that is distinct from “case _”. This is additional
syntax. When asked what the use case was for these suggestions, he said he
wants to distinguish between known and unknown cases at the beginning of
the switch.


>
> What do you gain from writing the unknown case first?
>
> I know where to look for the failure cases.  I also tend put a bunch of
> guard statements near the beginning of a function.  It is just a
> programming style.
>
> With my behavior of ‘unexpected:’ you can put it wherever you want.  Why
> limit that by forcing it to go at the end?
>

As pointed out earlier (by one of the core team members, I think),
meaningful resilience would mean that the unexpected or unknown case should
have useful work executed at runtime; the intention is that the user
*shouldn’t* be treating it as a runtime “failure case,” as it effectively
makes adding an enum case a change that is incompatible with existing
binaries (i.e., not terribly resilient).

As you and I seem to agree, reaching an unexpected case requires at least
notionally considering which cases are expected in the first place. This is
the dictionary definition of a default, and Swift usage is to put the
default case at the end of a switch statement. Adding new syntax as Cheyo
suggests to enable putting it elsewhere, merely for “style,” doesn’t seem
to pass the bar for new syntax, nor is it consistent with existing Swift
usage.

Isn't this basically the same thing as asking for the ability to write the
> default case first, a frequently suggested and rejected syntax addition?
>
>
> No.  I don’t think I have ever heard that asked for,
>

It has been asked for more than once on this list.

but putting default in a different place has a different meaning.  The way
> I read a switch statement anyway is that it tries each case until it find
> one that matches.  Default matches everything, so it has to go at the end
> (since it will always match and nothing afterwards will be tried).
>
> Having ‘unexpected:’ also match known/expected cases is problematic as a
> mental model.  I think that is just an artifact of the original proposal
> using default.  There is no reason 'unexpected:’ should have to handle
> known cases as well… let’s just 

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] [Review] SE 0192 - Non-Exhaustive Enums

2018-01-05 Thread Jonathan Hull via swift-evolution

> On Jan 4, 2018, at 11:02 PM, Xiaodi Wu  wrote:
> 
> 
> On Fri, Jan 5, 2018 at 01:56 Jonathan Hull  > wrote:
>> On Jan 4, 2018, at 10:31 PM, Xiaodi Wu via swift-evolution 
>> > wrote:
> 
>> 
>> On Fri, Jan 5, 2018 at 00:21 Cheyo Jimenez > > wrote:
> 
>> 
>> On Jan 4, 2018, at 4:37 PM, Xiaodi Wu > > wrote:
>> 
> 
>>> On Thu, Jan 4, 2018 at 19:29 Cheyo J. Jimenez >> > wrote:
>>> 
>>> We seem to agree that, by virtue of not supporting use in a pattern and 
>>> being placed at the end, the feature is a flavor of default. I’m still not 
>>> sure I understand why you believe it should not be a flavor of default 
>>> going forward.
>>> 
 
 You still haven’t answered my question, though—what’s the use case for the 
 feature you propose?
>>> 
>>> My use case would be distinguishing between compile time known cases vs 
>>> “future only” cases (or unknown cases).
>>> 
>>> I understand that the feature you propose would allow you to make such a 
>>> distinction, but again, what is your use case for doing so?
> 
>> Breaking out early by checking unknown cases first. I admit this is not deal 
>> breaker, just a different style I’d like to see supported in the future. 
> 
>> 
>> I'm still not sure I understand. How can the machine know that it's dealing 
>> with an unknown case without first checking if it matches any known case?
> 
> 
> I had the same thought as Cheyo.  It isn’t a deal breaker… I like the 
> compromise, but I would prefer it trigger only on an actual unknown case (as 
> opposed to acting like default). I like to break failure cases out at the top 
> when possible. I don’t see any good reason not to support that style.
> 
> To answer your question, in the naive sense, it basically is the same 
> question as asking if it is a known case (and then taking the inverse). That 
> doesn’t mean actually checking each case separately though. For example, if 
> the enum cases are internally represented as an unsigned integer, and they 
> are all together in a block, the compiler could simply check that it is 
> greater than the max known value. You could probably even do a bit mask 
> comparison in some cases...
> 
> These are obvious optimizations, but why does this require new syntax?

I am not sure I understand what you are asking. There isn’t additional syntax.  
We are just arguing over the name + behavior of ‘unexpected:’.  You want it to 
behave like ‘default’ and I am saying that stops the use case I mention above.


> What do you gain from writing the unknown case first?
I know where to look for the failure cases.  I also tend put a bunch of guard 
statements near the beginning of a function.  It is just a programming style.

With my behavior of ‘unexpected:’ you can put it wherever you want.  Why limit 
that by forcing it to go at the end?

> Isn't this basically the same thing as asking for the ability to write the 
> default case first, a frequently suggested and rejected syntax addition?

No.  I don’t think I have ever heard that asked for, but putting default in a 
different place has a different meaning.  The way I read a switch statement 
anyway is that it tries each case until it find one that matches.  Default 
matches everything, so it has to go at the end (since it will always match and 
nothing afterwards will be tried).

Having ‘unexpected:’ also match known/expected cases is problematic as a mental 
model.  I think that is just an artifact of the original proposal using 
default.  There is no reason 'unexpected:’ should have to handle known cases as 
well… let’s just have it trigger on unexpected ones.

Thanks,
Jon


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