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

2018-01-04 Thread Jordan Rose via swift-evolution
I'll admit I hadn't thought of using "unknown default" (or "default unknown"). 
I don't think that's terrible, but I mildly prefer `unknown case` because it 
builds on the "pun" that enum elements are also defined using 'case'. If 
anything hits this part of the switch, it really will be an "unknown case", 
i.e. a statically-unknown enum element.

To Cheyo's point, if this were to be a single token I'd probably spell it 
#unknown, like #available. Then we'd have `case #unknown:` and something that 
naturally expands to other pattern positions. I found that less aesthetically 
pleasing, though, and so a context-sensitive keyword seemed like the way to go.

(For the record, though, I wouldn't describe `case _` as a special case of 
`default`. They do exactly the same thing, and `_` is a useful pattern in other 
contexts, so if anything the current `default` should be thought of as 
syntactic sugar for `case _`.)

I'll add these points to the "Alternatives Considered" section in the PR later 
today.

Jordan


> On Jan 3, 2018, at 22:56, Xiaodi Wu  wrote:
> 
> As has already been said, “case unknown” is source-breaking because it 
> conflicts with any real cases named “unknown”; “\unknown” looks like a key 
> path but isn’t, and I wonder if it would potentially conflict with existing 
> key paths.
> 
> In any case, my point was not to bikeshed the “unknown” part, but to ask 
> whether any consideration had been made to have the feature presented as a 
> flavor of default instead of a flavor of case.
> 
> On Wed, Jan 3, 2018 at 23:57 Cheyo Jimenez  > wrote:
> 
> 
> On Jan 3, 2018, at 6:52 PM, Xiaodi Wu via swift-evolution 
> > wrote:
> 
>> This is a very nice revision. One bikeshedding thought:
>> 
>> Since "unknown case" is presented as a special kind of "default", can't be 
>> mixed with "default", and can't be used in case patterns, why not "default 
>> unknown" (or "unknown default") instead of "unknown case"?
> 
> `case _ :` is already a special case of default. 
> I’d rather have `case unknown :`
> `unknown case :` is weird because of the order of `case`. 
> 
> Another alternative is `case \unknown :`
> `\unknown` would also allow pattern matching. 
> 
> 
> 
>> 
>> 
>> On Wed, Jan 3, 2018 at 8:05 PM, Jordan Rose via swift-evolution 
>> > wrote:
>>> On Jan 2, 2018, at 18:07, Jordan Rose >> > wrote:
>>> 
>>> [Proposal: 
>>> https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md
>>>  
>>> ]
>>> 
>>> Whew! Thanks for your feedback, everyone. On the lighter side of 
>>> feedback—naming things—it seems that most people seem to like '@frozen', 
>>> and that does in fact have the connotations we want it to have. I like it 
>>> too.
>>> 
>>> More seriously, this discussion has convinced me that it's worth including 
>>> what the proposal discusses as a 'future' case. The key point that swayed 
>>> me is that this can produce a warning when the switch is missing a case 
>>> rather than an error, which both provides the necessary compiler feedback 
>>> to update your code and allows your dependencies to continue compiling when 
>>> you update to a newer SDK. I know people on both sides won't be 100% 
>>> satisfied with this, but does it seem like a reasonable compromise?
>>> 
>>> The next question is how to spell it. I'm leaning towards `unexpected 
>>> case:`, which (a) is backwards-compatible, and (b) also handles "private 
>>> cases", either the fake kind that you can do in C (as described in the 
>>> proposal), or some real feature we might add to Swift some day. `unknown 
>>> case:` isn't bad either.
>>> 
>>> I too would like to just do `unknown:` or `unexpected:` but that's 
>>> technically a source-breaking change:
>>> 
>>> switch foo {
>>> case bar:
>>>   unknown:
>>>   while baz() {
>>> while garply() {
>>>   if quux() {
>>> break unknown
>>>   }
>>> }
>>>   }
>>> }
>>> 
>>> Another downside of the `unexpected case:` spelling is that it doesn't work 
>>> as part of a larger pattern. I don't have a good answer for that one, but 
>>> perhaps it's acceptable for now.
>>> 
>>> I'll write up a revision of the proposal soon and make sure the core team 
>>> gets my recommendation when they discuss the results of the review.
>>> 
>>> ---
>>> 
>>> I'll respond to a few of the more intricate discussions tomorrow, including 
>>> the syntax of putting a new declaration inside the enum rather than 
>>> outside. Thank you again, everyone, and happy new year!
>> 
>> I ended up doing these in the opposite order, writing up the new proposal 
>> first and not yet responding to the discussion that's further out. You can 
>> read 

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

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

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


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

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

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


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

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

> On Jan 4, 2018, at 11:53 AM, Xiaodi Wu  wrote:
> 
> 
> On Thu, Jan 4, 2018 at 13:46 Cheyo Jimenez  > wrote:
> 
> 
> On Jan 4, 2018, at 10:49 AM, Jordan Rose  > wrote:
> 
>> I'll admit I hadn't thought of using "unknown default" (or "default 
>> unknown"). I don't think that's terrible, but I mildly prefer `unknown case` 
>> because it builds on the "pun" that enum elements are also defined using 
>> 'case'. If anything hits this part of the switch, it really will be an 
>> "unknown case", i.e. a statically-unknown enum element.
>> 
>> To Cheyo's point, if this were to be a single token I'd probably spell it 
>> #unknown, like #available. Then we'd have `case #unknown:` and something 
>> that naturally expands to other pattern positions. I found that less 
>> aesthetically pleasing, though, and so a context-sensitive keyword seemed 
>> like the way to go.
>> 
>> (For the record, though, I wouldn't describe `case _` as a special case of 
>> `default`. They do exactly the same thing, and `_` is a useful pattern in 
>> other contexts, so if anything the current `default` should be thought of as 
>> syntactic sugar for `case _`.)
> 
> Can case _ be mixed with unknown case? How can we match all compile time 
> known cases but exclude future cases?
> 
> What’s your use case for that? That eliminates the possibility of “unknown 
> case” giving you compile-time warnings for subsequently added cases, which 
> was the entire purpose of adding the syntax in the first place.

I was thinking of a generalized `unknown case` pattern but that is out of scope 
for this proposal. 

 

switch excuse {
 case .eatenByPet :
   //…
 unknown case:
   // …
 case _:
   // …
 }

> 
> Should there be something like `case *` that would capture all currently 
> known cases during compile time? case * and case _ would be the same in 
> exhaustive enums. 

This is why I was suggesting another pattern that only captures known cases at 
compile time:

switch excuse {
 case .eatenByPet :
   //…
 case * : //  All cases captured at compile time. 
   // …
 unknown case:
   // …
 }

> 
> 
>> 
>> I'll add these points to the "Alternatives Considered" section in the PR 
>> later today.
>> 
>> Jordan
>> 
>> 
>>> On Jan 3, 2018, at 22:56, Xiaodi Wu >> > wrote:
>>> 
>>> As has already been said, “case unknown” is source-breaking because it 
>>> conflicts with any real cases named “unknown”; “\unknown” looks like a key 
>>> path but isn’t, and I wonder if it would potentially conflict with existing 
>>> key paths.
>>> 
>>> In any case, my point was not to bikeshed the “unknown” part, but to ask 
>>> whether any consideration had been made to have the feature presented as a 
>>> flavor of default instead of a flavor of case.
>>> 
>>> On Wed, Jan 3, 2018 at 23:57 Cheyo Jimenez >> > wrote:
>>> 
>>> 
>>> On Jan 3, 2018, at 6:52 PM, Xiaodi Wu via swift-evolution 
>>> > wrote:
>>> 
 This is a very nice revision. One bikeshedding thought:
 
 Since "unknown case" is presented as a special kind of "default", can't be 
 mixed with "default", and can't be used in case patterns, why not "default 
 unknown" (or "unknown default") instead of "unknown case"?
>>> 
>>> `case _ :` is already a special case of default. 
>>> I’d rather have `case unknown :`
>>> `unknown case :` is weird because of the order of `case`. 
>>> 
>>> Another alternative is `case \unknown :`
>>> `\unknown` would also allow pattern matching. 
>>> 
>>> 
>>> 
 
 
 On Wed, Jan 3, 2018 at 8:05 PM, Jordan Rose via swift-evolution 
 > wrote:
> On Jan 2, 2018, at 18:07, Jordan Rose  > wrote:
> 
> [Proposal: 
> https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md
>  
> ]
> 
> Whew! Thanks for your feedback, everyone. On the lighter side of 
> feedback—naming things—it seems that most people seem to like '@frozen', 
> and that does in fact have the connotations we want it to have. I like it 
> too.
> 
> More seriously, this discussion has convinced me that it's worth 
> including what the proposal discusses as a 'future' case. The key point 
> that swayed me is that this can produce a warning when the switch is 
> missing a case rather than an error, which both provides the necessary 
> compiler feedback to update your code and allows your dependencies to 
> 

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

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

> On Jan 4, 2018, at 3:50 PM, Xiaodi Wu  wrote:
> 
> 
> On Thu, Jan 4, 2018 at 18:39 Cheyo J. Jimenez  > wrote:
> 
>> On Jan 4, 2018, at 2:55 PM, Xiaodi Wu > > wrote:
>> 
>> 
>> On Thu, Jan 4, 2018 at 17:15 Cheyo J. Jimenez > > wrote:
>>> On Jan 4, 2018, at 11:53 AM, Xiaodi Wu >> > wrote:
>>> 
>>> 
>>> On Thu, Jan 4, 2018 at 13:46 Cheyo Jimenez >> > wrote:
>>> 
>>> 
>>> On Jan 4, 2018, at 10:49 AM, Jordan Rose >> > wrote:
>>> 
 I'll admit I hadn't thought of using "unknown default" (or "default 
 unknown"). I don't think that's terrible, but I mildly prefer `unknown 
 case` because it builds on the "pun" that enum elements are also defined 
 using 'case'. If anything hits this part of the switch, it really will be 
 an "unknown case", i.e. a statically-unknown enum element.
 
 To Cheyo's point, if this were to be a single token I'd probably spell it 
 #unknown, like #available. Then we'd have `case #unknown:` and something 
 that naturally expands to other pattern positions. I found that less 
 aesthetically pleasing, though, and so a context-sensitive keyword seemed 
 like the way to go.
 
 (For the record, though, I wouldn't describe `case _` as a special case of 
 `default`. They do exactly the same thing, and `_` is a useful pattern in 
 other contexts, so if anything the current `default` should be thought of 
 as syntactic sugar for `case _`.)
>>> 
>>> Can case _ be mixed with unknown case? How can we match all compile time 
>>> known cases but exclude future cases?
>>> 
>>> What’s your use case for that? That eliminates the possibility of “unknown 
>>> case” giving you compile-time warnings for subsequently added cases, which 
>>> was the entire purpose of adding the syntax in the first place.
>> 
>> I was thinking of a generalized `unknown case` pattern but that is out of 
>> scope for this proposal. 
>> 
>>  
>> 
>> switch excuse {
>>  case .eatenByPet :
>>//…
>>  unknown case:
>>// …
>>  case _:
>>// …
>>  }
>> 
>>> 
>>> Should there be something like `case *` that would capture all currently 
>>> known cases during compile time? case * and case _ would be the same in 
>>> exhaustive enums. 
>> 
>> This is why I was suggesting another pattern that only captures known cases 
>> at compile time:
>> 
>> switch excuse {
>>  case .eatenByPet :
>>//…
>>  case * : //  All cases captured at compile time. 
>>// …
>>  unknown case:
>>// …
>>  }
>> 
>> Sorry, I don’t understand. However you spell it, what is your use case for 
>> this? The stated purpose of “unknown case” is to gain compile-time 
>> exhaustiveness testing, but this would not allow for that.
> 
> 
> 
> 
> switch (excuse, notifiedTeacherBeforeDeadline) {
> case (.eatenByPet, true):
>   // …
> case (.thoughtItWasDueNextWeek, true):
>   // …
> case (unknown case, true):
>   // …
> case (_, false):
>   // …
> }
> 
> Im referring to the future direction section in the new PR 
> .
>  The above example if from there. 
> 
> I am fine with `unknown case` being required to be at the end of the switch 
> for now. 
> 
> I think of `unknown case` as a pattern that only matches unknown cases no 
> matter where on the switch it is.
> 
> This is why I do not think that `default unknown` would work well once 
> `unknown case` can be used a pattern.
> 
> We can start a new thread on this if you’d like. 
> 
> The reason I put forward “default unknown” is precisely because the proposed 
> feature *cannot* be used in a pattern and therefore seems more apt as not a 
> case.
> 
It can not be used in a pattern now but you could in the future if left as 
`case`. 

> It actually makes it more natural to use in the given example above because 
> “default unknown” could actually be used to provide compile-time 
> exhaustiveness checking for such a tuple pattern, whereas without being able 
> to use “unknown case” in a pattern you can’t write “case (unknown case, _)”.

The way `unknown case` enforces  compile-time exhaustiveness is by only 
matching unknown cases. The implementation may be more close to default by the 
virtue of being forced to go at the end of the switch statement now but that 
should not dictate the user experience. 

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

Re: [swift-evolution] DynamicMemberLookup proposal: status update

2018-01-04 Thread Nevin Brackett-Rozinsky via swift-evolution
There’s a lot of information here and it’ll take some time to process it
all. My initial reaction is that a “strong type-alias” feature might help.
If one could write (strawman syntax):

strong typealias Dog = PyVal// A semantically independent new type

extension Dog {
// Declarations here are only available on “Dog”, not on “PyVal”
}

then most of the overload issues would evaporate.

Nevin



On Thu, Jan 4, 2018 at 3:52 PM, Chris Lattner via swift-evolution <
swift-evolution@swift.org> 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
>
>
> *A Swift automatic wrapper facility:*
>
> Requirements:
>  - We want the be able to run a user defined script to generate wrappers.
>  - This script can have arbitrary dependencies and should get updated when
> one of them change.
>  - These dependencies won’t be visible to the Xcode build system, so the
> compiler will have to manage them.
>  - In principle, one set of wrappers should be able to depend on another
> set, and wants “overlays”, so we need a pretty general model.
>
> I don’t think the clang modules based approach is a good way to go.
>
>
> *Proposed Approach: Tighter integration between SwiftPM and Swift*
>
> The model is that you should be able to say (strawman syntax):
>
>import Foo from http://github.com/whatever/mypackage
>import Bar from file:///some/path/on/my/machine
>
> and have the compiler ask SwiftPM to build and cache the specified module
> onto your local disk, then have the compiler load it like any other
> module.  This means that “generated wrappers” is now a SwiftPM/llbuild
> feature, and we can use the SwiftPM “language” to describe things like:
>
> 1. Information about what command line invocation is required to generate
> the wrappers.
> 2. Dependency information so that the compiler can regenerate the wrappers
> when they are out of date.
> 3. Platform abstraction tools since things are in different locations on
> linux vs mac, Python 2 vs Python 3 is also something that would have to be
> handled somehow.
> 4. The directory could contain manually written .swift code, serving the
> function similar to “overlays” to augment the automatic wrappers generated.
>
> We care about Playgrounds and the REPL, and they should be able to work
> with this model.
>
> I think that this would be a very nice and useful feature.
>
>
> *Using Wrappers to implement Python Interop:*
>
> While such a thing would be generally useful, it is important to explore
> how well this will work to solve the actual problem at hand, since this is
> being pitched as an alternative to DynamicMemberLookup.  Here is the
> example from the list:
>
> class BankAccount:
> def __init__(self, initial_balance: int = 0) -> None:
> self.balance = initial_balance
> def deposit(self, amount: int) -> None:
> self.balance += amount
> def withdraw(self, amount: int) -> None:
> self.balance -= amount
> def overdrawn(self) -> bool:
> return self.balance < 0
>
> my_account = BankAccount(15)
> my_account.withdraw(5)print(my_account.balance)
>
>
> The idea is to generate a wrapper like this (potentially including the
> type annotations as a refinement):
>
> typealias BankAccount = PyVal
> extension PyVal { // methods on BankAccount
>   init(initial_balance: PyVal) { … }
>   func deposit(amount: PyVal) -> PyVal { … }
>   func withdraw(amount: PyVal) -> PyVal { … }
>   func overdrawn() -> PyVal { … }
> }
>
> my_account = BankAccount(initial_balance: 15)
> my_account.withdraw(amount: 5)
> print(my_account.balance)
>
>
>
> It is worth pointing out that this approach is very analogous to the “type
> providers” feature that Joe pushed hard for months ago, it is just a
> different implementation approach.  The proposal specifically explains why
> this isn’t a great solution here:
> https://gist.github.com/lattner/b016e1cf86c43732c8d82f90e5ae54

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

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

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


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

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

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

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

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

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

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


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

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

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

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

- If a 

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

2018-01-04 Thread Xiaodi Wu via swift-evolution
On Thu, Jan 4, 2018 at 19:29 Cheyo J. Jimenez  wrote:

> On Jan 4, 2018, at 3:50 PM, Xiaodi Wu  wrote:
>
>
> On Thu, Jan 4, 2018 at 18:39 Cheyo J. Jimenez  wrote:
>
>>
>> On Jan 4, 2018, at 2:55 PM, Xiaodi Wu  wrote:
>>
>>
>> On Thu, Jan 4, 2018 at 17:15 Cheyo J. Jimenez 
>> wrote:
>>
>>> On Jan 4, 2018, at 11:53 AM, Xiaodi Wu  wrote:
>>>
>>>
>>> On Thu, Jan 4, 2018 at 13:46 Cheyo Jimenez  wrote:
>>>


 On Jan 4, 2018, at 10:49 AM, Jordan Rose  wrote:

 I'll admit I hadn't thought of using "unknown default" (or "default
 unknown"). I don't think that's terrible, but I mildly prefer `unknown
 case` because it builds on the "pun" that enum elements are also defined
 using 'case'. If anything hits this part of the switch, it really will be
 an "unknown case", i.e. a statically-unknown enum element.

 To Cheyo's point, if this *were* to be a single token I'd probably
 spell it #unknown, like #available. Then we'd have `case #unknown:` and
 something that naturally expands to other pattern positions. I found that
 less aesthetically pleasing, though, and so a context-sensitive keyword
 seemed like the way to go.

 (For the record, though, I wouldn't describe `case _` as a special case
 of `default`. They do exactly the same thing, and `_` is a useful pattern
 in other contexts, so if anything the current `default` should be thought
 of as syntactic sugar for `case _`.)


 Can case _ be mixed with unknown case? How can we match all compile
 time known cases but exclude future cases?

>>>
>>> What’s your use case for that? That eliminates the possibility of
>>> “unknown case” giving you compile-time warnings for subsequently added
>>> cases, which was the entire purpose of adding the syntax in the first place.
>>>
>>>
>>> I was thinking of a generalized `unknown case` pattern but that is out
>>> of scope for this proposal.
>>> 
>>>
>>>
>>> switch excuse {
>>>  case .eatenByPet :
>>>//…
>>>  unknown case:
>>>// …
>>>  case _:
>>>// …
>>>  }
>>>
>>>
>>> Should there be something like `case *` that would capture all currently
 known cases during compile time? case * and case _ would be the same in
 exhaustive enums.

>>>
>>> This is why I was suggesting another pattern that only captures known
>>> cases at compile time:
>>>
>>> switch excuse {
>>>  case .eatenByPet :
>>>//…
>>>  case * : //  All cases captured at compile time.
>>>// …
>>>  unknown case:
>>>// …
>>>  }
>>>
>>
>> Sorry, I don’t understand. However you spell it, what is your use case
>> for this? The stated purpose of “unknown case” is to gain compile-time
>> exhaustiveness testing, but this would not allow for that.
>>
>>
>>
>>
>>
>> switch (excuse, notifiedTeacherBeforeDeadline) {case (.eatenByPet, true):
>>   // …case (.thoughtItWasDueNextWeek, true):
>>   // …case (unknown case, true):
>>   // …case (_, false):
>>   // …}
>>
>>
>> Im referring to the future direction section in the new PR
>> .
>> The above example if from there.
>>
>> I am fine with `unknown case` being required to be at the end of the
>> switch for now.
>>
>> I think of `unknown case` as a pattern that only matches unknown cases no
>> matter where on the switch it is.
>>
>> This is why I do not think that `default unknown` would work well once
>> `unknown case` can be used a pattern.
>>
>> We can start a new thread on this if you’d like.
>>
>
> The reason I put forward “default unknown” is precisely because the
> proposed feature *cannot* be used in a pattern and therefore seems more apt
> as not a case.
>
> It can not be used in a pattern now but you could in the future if left as
> `case`.
>
>
> It actually makes it more natural to use in the given example above
> because “default unknown” could actually be used to provide compile-time
> exhaustiveness checking for such a tuple pattern, whereas without being
> able to use “unknown case” in a pattern you can’t write “case (unknown
> case, _)”.
>
>
> The way `unknown case` enforces  compile-time exhaustiveness is by only
> matching unknown cases. The implementation may be more close to default by
> the virtue of being forced to go at the end of the switch statement now but
> that should not dictate the user experience.
>

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 

Re: [swift-evolution] DynamicMemberLookup proposal: status update

2018-01-04 Thread Chris Lattner via swift-evolution
On Jan 4, 2018, at 3:43 PM, Nevin Brackett-Rozinsky 
 wrote:
> 
> There’s a lot of information here and it’ll take some time to process it all. 
> My initial reaction is that a “strong type-alias” feature might help. If one 
> could write (strawman syntax):
> 
> strong typealias Dog = PyVal// A semantically independent new type
> 
> extension Dog {
> // Declarations here are only available on “Dog”, not on “PyVal”
> }
> 
> then most of the overload issues would evaporate.

Until and if there were an acceptable design for such a feature, it is 
impossible to say whether it would help.  I am personally skeptical that 
"strong type aliases" will ever make it into Swift.

-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-04 Thread Xiaodi Wu via swift-evolution
On Thu, Jan 4, 2018 at 17:15 Cheyo J. Jimenez  wrote:

> On Jan 4, 2018, at 11:53 AM, Xiaodi Wu  wrote:
>
>
> On Thu, Jan 4, 2018 at 13:46 Cheyo Jimenez  wrote:
>
>>
>>
>> On Jan 4, 2018, at 10:49 AM, Jordan Rose  wrote:
>>
>> I'll admit I hadn't thought of using "unknown default" (or "default
>> unknown"). I don't think that's terrible, but I mildly prefer `unknown
>> case` because it builds on the "pun" that enum elements are also defined
>> using 'case'. If anything hits this part of the switch, it really will be
>> an "unknown case", i.e. a statically-unknown enum element.
>>
>> To Cheyo's point, if this *were* to be a single token I'd probably spell
>> it #unknown, like #available. Then we'd have `case #unknown:` and something
>> that naturally expands to other pattern positions. I found that less
>> aesthetically pleasing, though, and so a context-sensitive keyword seemed
>> like the way to go.
>>
>> (For the record, though, I wouldn't describe `case _` as a special case
>> of `default`. They do exactly the same thing, and `_` is a useful pattern
>> in other contexts, so if anything the current `default` should be thought
>> of as syntactic sugar for `case _`.)
>>
>>
>> Can case _ be mixed with unknown case? How can we match all compile time
>> known cases but exclude future cases?
>>
>
> What’s your use case for that? That eliminates the possibility of “unknown
> case” giving you compile-time warnings for subsequently added cases, which
> was the entire purpose of adding the syntax in the first place.
>
>
> I was thinking of a generalized `unknown case` pattern but that is out of
> scope for this proposal.
> 
>
>
> switch excuse {
>  case .eatenByPet :
>//…
>  unknown case:
>// …
>  case _:
>// …
>  }
>
>
> Should there be something like `case *` that would capture all currently
>> known cases during compile time? case * and case _ would be the same in
>> exhaustive enums.
>>
>
> This is why I was suggesting another pattern that only captures known
> cases at compile time:
>
> switch excuse {
>  case .eatenByPet :
>//…
>  case * : //  All cases captured at compile time.
>// …
>  unknown case:
>// …
>  }
>

Sorry, I don’t understand. However you spell it, what is your use case for
this? The stated purpose of “unknown case” is to gain compile-time
exhaustiveness testing, but this would not allow for that.



>
>>
>>
>> I'll add these points to the "Alternatives Considered" section in the PR
>> later today.
>>
>> Jordan
>>
>>
>> On Jan 3, 2018, at 22:56, Xiaodi Wu  wrote:
>>
>> As has already been said, “case unknown” is source-breaking because it
>> conflicts with any real cases named “unknown”; “\unknown” looks like a key
>> path but isn’t, and I wonder if it would potentially conflict with existing
>> key paths.
>>
>> In any case, my point was not to bikeshed the “unknown” part, but to ask
>> whether any consideration had been made to have the feature presented as a
>> flavor of default instead of a flavor of case.
>>
>> On Wed, Jan 3, 2018 at 23:57 Cheyo Jimenez  wrote:
>>
>>>
>>>
>>> On Jan 3, 2018, at 6:52 PM, Xiaodi Wu via swift-evolution <
>>> swift-evolution@swift.org> wrote:
>>>
>>> This is a very nice revision. One bikeshedding thought:
>>>
>>> Since "unknown case" is presented as a special kind of "default", can't
>>> be mixed with "default", and can't be used in case patterns, why not
>>> "default unknown" (or "unknown default") instead of "unknown case"?
>>>
>>>
>>> `case _ :` is already a special case of default.
>>> I’d rather have `case unknown :`
>>> `unknown case :` is weird because of the order of `case`.
>>>
>>> Another alternative is `case \unknown :`
>>> `\unknown` would also allow pattern matching.
>>>
>>>
>>>
>>>
>>>
>>> On Wed, Jan 3, 2018 at 8:05 PM, Jordan Rose via swift-evolution <
>>> swift-evolution@swift.org> wrote:
>>>
 On Jan 2, 2018, at 18:07, Jordan Rose  wrote:

 [Proposal:
 https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md
 ]

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

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

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

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

> On Jan 4, 2018, at 2:55 PM, Xiaodi Wu  wrote:
> 
> 
> On Thu, Jan 4, 2018 at 17:15 Cheyo J. Jimenez  > wrote:
>> On Jan 4, 2018, at 11:53 AM, Xiaodi Wu > > wrote:
>> 
>> 
>> On Thu, Jan 4, 2018 at 13:46 Cheyo Jimenez > > wrote:
>> 
>> 
>> On Jan 4, 2018, at 10:49 AM, Jordan Rose > > wrote:
>> 
>>> I'll admit I hadn't thought of using "unknown default" (or "default 
>>> unknown"). I don't think that's terrible, but I mildly prefer `unknown 
>>> case` because it builds on the "pun" that enum elements are also defined 
>>> using 'case'. If anything hits this part of the switch, it really will be 
>>> an "unknown case", i.e. a statically-unknown enum element.
>>> 
>>> To Cheyo's point, if this were to be a single token I'd probably spell it 
>>> #unknown, like #available. Then we'd have `case #unknown:` and something 
>>> that naturally expands to other pattern positions. I found that less 
>>> aesthetically pleasing, though, and so a context-sensitive keyword seemed 
>>> like the way to go.
>>> 
>>> (For the record, though, I wouldn't describe `case _` as a special case of 
>>> `default`. They do exactly the same thing, and `_` is a useful pattern in 
>>> other contexts, so if anything the current `default` should be thought of 
>>> as syntactic sugar for `case _`.)
>> 
>> Can case _ be mixed with unknown case? How can we match all compile time 
>> known cases but exclude future cases?
>> 
>> What’s your use case for that? That eliminates the possibility of “unknown 
>> case” giving you compile-time warnings for subsequently added cases, which 
>> was the entire purpose of adding the syntax in the first place.
> 
> I was thinking of a generalized `unknown case` pattern but that is out of 
> scope for this proposal. 
> 
>  
> 
> switch excuse {
>  case .eatenByPet :
>//…
>  unknown case:
>// …
>  case _:
>// …
>  }
> 
>> 
>> Should there be something like `case *` that would capture all currently 
>> known cases during compile time? case * and case _ would be the same in 
>> exhaustive enums. 
> 
> This is why I was suggesting another pattern that only captures known cases 
> at compile time:
> 
> switch excuse {
>  case .eatenByPet :
>//…
>  case * : //  All cases captured at compile time. 
>// …
>  unknown case:
>// …
>  }
> 
> Sorry, I don’t understand. However you spell it, what is your use case for 
> this? The stated purpose of “unknown case” is to gain compile-time 
> exhaustiveness testing, but this would not allow for that.




switch (excuse, notifiedTeacherBeforeDeadline) {
case (.eatenByPet, true):
  // …
case (.thoughtItWasDueNextWeek, true):
  // …
case (unknown case, true):
  // …
case (_, false):
  // …
}

Im referring to the future direction section in the new PR 
.
 The above example if from there. 

I am fine with `unknown case` being required to be at the end of the switch for 
now. 

I think of `unknown case` as a pattern that only matches unknown cases no 
matter where on the switch it is.

This is why I do not think that `default unknown` would work well once `unknown 
case` can be used a pattern.

We can start a new thread on this if you’d like. 

 

> 
> 
> 
>> 
>> 
>>> 
>>> I'll add these points to the "Alternatives Considered" section in the PR 
>>> later today.
>>> 
>>> Jordan
>>> 
>>> 
 On Jan 3, 2018, at 22:56, Xiaodi Wu > wrote:
 
 As has already been said, “case unknown” is source-breaking because it 
 conflicts with any real cases named “unknown”; “\unknown” looks like a key 
 path but isn’t, and I wonder if it would potentially conflict with 
 existing key paths.
 
 In any case, my point was not to bikeshed the “unknown” part, but to ask 
 whether any consideration had been made to have the feature presented as a 
 flavor of default instead of a flavor of case.
 
 On Wed, Jan 3, 2018 at 23:57 Cheyo Jimenez > wrote:
 
 
 On Jan 3, 2018, at 6:52 PM, Xiaodi Wu via swift-evolution 
 > wrote:
 
> This is a very nice revision. One bikeshedding thought:
> 
> Since "unknown case" is presented as a special kind of "default", can't 
> be mixed with "default", and can't be used in case patterns, why not 
> "default unknown" (or "unknown default") instead of "unknown case"?
 
 `case _ :` is already a special case of default. 

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

2018-01-04 Thread Xiaodi Wu via swift-evolution
On Thu, Jan 4, 2018 at 18:39 Cheyo J. Jimenez  wrote:

>
> On Jan 4, 2018, at 2:55 PM, Xiaodi Wu  wrote:
>
>
> On Thu, Jan 4, 2018 at 17:15 Cheyo J. Jimenez  wrote:
>
>> On Jan 4, 2018, at 11:53 AM, Xiaodi Wu  wrote:
>>
>>
>> On Thu, Jan 4, 2018 at 13:46 Cheyo Jimenez  wrote:
>>
>>>
>>>
>>> On Jan 4, 2018, at 10:49 AM, Jordan Rose  wrote:
>>>
>>> I'll admit I hadn't thought of using "unknown default" (or "default
>>> unknown"). I don't think that's terrible, but I mildly prefer `unknown
>>> case` because it builds on the "pun" that enum elements are also defined
>>> using 'case'. If anything hits this part of the switch, it really will be
>>> an "unknown case", i.e. a statically-unknown enum element.
>>>
>>> To Cheyo's point, if this *were* to be a single token I'd probably
>>> spell it #unknown, like #available. Then we'd have `case #unknown:` and
>>> something that naturally expands to other pattern positions. I found that
>>> less aesthetically pleasing, though, and so a context-sensitive keyword
>>> seemed like the way to go.
>>>
>>> (For the record, though, I wouldn't describe `case _` as a special case
>>> of `default`. They do exactly the same thing, and `_` is a useful pattern
>>> in other contexts, so if anything the current `default` should be thought
>>> of as syntactic sugar for `case _`.)
>>>
>>>
>>> Can case _ be mixed with unknown case? How can we match all compile time
>>> known cases but exclude future cases?
>>>
>>
>> What’s your use case for that? That eliminates the possibility of
>> “unknown case” giving you compile-time warnings for subsequently added
>> cases, which was the entire purpose of adding the syntax in the first place.
>>
>>
>> I was thinking of a generalized `unknown case` pattern but that is out
>> of scope for this proposal.
>> 
>>
>>
>> switch excuse {
>>  case .eatenByPet :
>>//…
>>  unknown case:
>>// …
>>  case _:
>>// …
>>  }
>>
>>
>> Should there be something like `case *` that would capture all currently
>>> known cases during compile time? case * and case _ would be the same in
>>> exhaustive enums.
>>>
>>
>> This is why I was suggesting another pattern that only captures known
>> cases at compile time:
>>
>> switch excuse {
>>  case .eatenByPet :
>>//…
>>  case * : //  All cases captured at compile time.
>>// …
>>  unknown case:
>>// …
>>  }
>>
>
> Sorry, I don’t understand. However you spell it, what is your use case for
> this? The stated purpose of “unknown case” is to gain compile-time
> exhaustiveness testing, but this would not allow for that.
>
>
>
>
>
> switch (excuse, notifiedTeacherBeforeDeadline) {case (.eatenByPet, true):
>   // …case (.thoughtItWasDueNextWeek, true):
>   // …case (unknown case, true):
>   // …case (_, false):
>   // …}
>
>
> Im referring to the future direction section in the new PR
> .
> The above example if from there.
>
> I am fine with `unknown case` being required to be at the end of the
> switch for now.
>
> I think of `unknown case` as a pattern that only matches unknown cases no
> matter where on the switch it is.
>
> This is why I do not think that `default unknown` would work well once
> `unknown case` can be used a pattern.
>
> We can start a new thread on this if you’d like.
>

The reason I put forward “default unknown” is precisely because the
proposed feature *cannot* be used in a pattern and therefore seems more apt
as not a case.

It actually makes it more natural to use in the given example above because
“default unknown” could actually be used to provide compile-time
exhaustiveness checking for such a tuple pattern, whereas without being
able to use “unknown case” in a pattern you can’t write “case (unknown
case, _)”.

You still haven’t answered my question, though—what’s the use case for the
feature you propose?


>
>
>
>
>
>>
>>>
>>>
>>> I'll add these points to the "Alternatives Considered" section in the PR
>>> later today.
>>>
>>> Jordan
>>>
>>>
>>> On Jan 3, 2018, at 22:56, Xiaodi Wu  wrote:
>>>
>>> As has already been said, “case unknown” is source-breaking because it
>>> conflicts with any real cases named “unknown”; “\unknown” looks like a key
>>> path but isn’t, and I wonder if it would potentially conflict with existing
>>> key paths.
>>>
>>> In any case, my point was not to bikeshed the “unknown” part, but to ask
>>> whether any consideration had been made to have the feature presented as a
>>> flavor of default instead of a flavor of case.
>>>
>>> On Wed, Jan 3, 2018 at 23:57 Cheyo Jimenez  wrote:
>>>


 On Jan 3, 2018, at 6:52 PM, Xiaodi Wu via 

[swift-evolution] DynamicMemberLookup proposal: status update

2018-01-04 Thread Chris Lattner via swift-evolution
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


A Swift automatic wrapper facility:

Requirements:
 - We want the be able to run a user defined script to generate wrappers.
 - This script can have arbitrary dependencies and should get updated when one 
of them change.
 - These dependencies won’t be visible to the Xcode build system, so the 
compiler will have to manage them.
 - In principle, one set of wrappers should be able to depend on another set, 
and wants “overlays”, so we need a pretty general model.

I don’t think the clang modules based approach is a good way to go.


Proposed Approach: Tighter integration between SwiftPM and Swift

The model is that you should be able to say (strawman syntax):

   import Foo from http://github.com/whatever/mypackage 

   import Bar from file:///some/path/on/my/machine 


and have the compiler ask SwiftPM to build and cache the specified module onto 
your local disk, then have the compiler load it like any other module.  This 
means that “generated wrappers” is now a SwiftPM/llbuild feature, and we can 
use the SwiftPM “language” to describe things like:

1. Information about what command line invocation is required to generate the 
wrappers.
2. Dependency information so that the compiler can regenerate the wrappers when 
they are out of date.
3. Platform abstraction tools since things are in different locations on linux 
vs mac, Python 2 vs Python 3 is also something that would have to be handled 
somehow.
4. The directory could contain manually written .swift code, serving the 
function similar to “overlays” to augment the automatic wrappers generated.

We care about Playgrounds and the REPL, and they should be able to work with 
this model.

I think that this would be a very nice and useful feature.  


Using Wrappers to implement Python Interop:

While such a thing would be generally useful, it is important to explore how 
well this will work to solve the actual problem at hand, since this is being 
pitched as an alternative to DynamicMemberLookup.  Here is the example from the 
list:
> class BankAccount:
> def __init__(self, initial_balance: int = 0) -> None:
> self.balance = initial_balance
> def deposit(self, amount: int) -> None:
> self.balance += amount
> def withdraw(self, amount: int) -> None:
> self.balance -= amount
> def overdrawn(self) -> bool:
> return self.balance < 0
> 
> my_account = BankAccount(15)
> my_account.withdraw(5)
> print(my_account.balance)


The idea is to generate a wrapper like this (potentially including the type 
annotations as a refinement):

typealias BankAccount = PyVal
extension PyVal { // methods on BankAccount
  init(initial_balance: PyVal) { … }
  func deposit(amount: PyVal) -> PyVal { … }
  func withdraw(amount: PyVal) -> PyVal { … }
  func overdrawn() -> PyVal { … }
}

my_account = BankAccount(initial_balance: 15)
my_account.withdraw(amount: 5)
print(my_account.balance)


It is worth pointing out that this approach is very analogous to the “type 
providers” feature that Joe pushed hard for months ago, it is just a different 
implementation approach.  The proposal specifically explains why this isn’t a 
great solution here:
https://gist.github.com/lattner/b016e1cf86c43732c8d82f90e5ae5438#introduce-f-style-type-providers-into-swift
 


That said, while there are similarities, there are also differences with type 
providers.  Here are the problems that I foresee:


1) This design still requires DynamicMemberLookup

This is because Python doesn’t have property declarations for the wrapper 
generator to process.  The code above shows this on the last line: since there 
is no definition of the “balance" property, there will be no “balance member” 
declared in the PyVal extension.  

Re: [swift-evolution] Preserving non-mutability of methods of an existential or generic object

2018-01-04 Thread Hooman Mehr via swift-evolution


> On Jan 3, 2018, at 6:45 PM, Slava Pestov  wrote:
>> On Jan 3, 2018, at 5:33 PM, Hooman Mehr > > wrote:
>> Thank you Slava, it is a very insightful answer. 
>> It also reveals a potential source for hard to track bugs. To make it easier 
>> to see, lets add state to class C:
>> 
>> class D: C { var state = 0 }
>> var d = D() // Bad but common habit of declaring objects as var
>> for i in 1...5 { d.f(i); d.state += 1 }
>> print(d.state) // Prints 1
>> 
>> The result is surprising because a typical programmer does not expect an 
>> object to have mutating methods (that replace the object itself with a 
>> different one).
>> I think this is a bug in Swift compiler. It should not let a class “inherit” 
>> a mutating method in this manner. Compiler should require a non-mutating 
>> declaration of `f()` to satisfy `P` conformance for a class type.
> 
> Perhaps, but it’s also possible to define a mutating method g() in a protocol 
> extension of P, where g() is not a protocol requirement. Calling g() on a 
> class instance can “replace” self in this manner also.

Is this desirable? It seems that Swift compiler generally tries to prevent you 
from defining mutating methods on class types and this situation feels like a 
flaw/bug that needs fixing. I think this can even have security implications 
(letting a malicious coder obfuscate a code put in place to create a backdoor).

>> If we fix the above, it should be possible to do what I asked in my post: 
>> When compiler knows an existential is an object, it should know all methods 
>> are non-mutating and accept `let` declaration despite calls to nominally 
>> mutating methods. Also, if a protocol refines another protocol to be 
>> class-bound, compiler should automatically refine all of its inherited 
>> mutating methods to be non-mutating and allow `let` declaration of an 
>> existential of that protocol even if there are calls to those originally 
>> mutating methods. 
> 
> This will prevent you from defining default implementations of protocol 
> requirements in protocol extensions, which would be a source-breaking change 
> at this point. I don’t think we can make such a change now.

I don’t think a mutating default implementation makes any sense for a class 
type. I think we should handle default implementation for class type with a 
constrained/refined extension that provides a non-mutating default 
implementation for the cases when a class type conforms to a non-class bound 
protocol. This seems to be impossible at the moment, but I see it as another 
shortcoming in the compiler, not a source breaking change for the sake of 
providing an obscure new feature.

> 
> Slava
> 
>> 
>> Hooman
>> 
>>> On Dec 21, 2017, at 10:59 PM, Slava Pestov >> > wrote:
>>> 
>>> Hi Hooman,
>>> 
>>> Since the protocol P is not class-bounded, the requirement can be witnessed 
>>> by a protocol extension method which re-assigns ‘self’:
>>> 
>>> protocol Initable {
>>>   init()
>>> }
>>> 
>>> extension P where Self : Initable {
>>>   mutating func f(_ x: Int) -> Int {
>>> self = Self()
>>> return x
>>>   }
>>> }
>>> 
>>> class C : P, Initable {
>>>   required init() {}
>>> }
>>> 
>>> Now imagine you could do this,
>>> 
>>> let x: P & AnyObject
>>> 
>>> x.f(12)
>>> 
>>> This would be invalid because ‘x’ is a let binding but the requirement ‘f’ 
>>> is witnessed by the protocol extension method, which performs a mutating 
>>> access of ‘self’.
>>> 
>>> Slava
>>> 
 On Dec 21, 2017, at 6:01 PM, Hooman Mehr via swift-evolution 
 > wrote:
 
 The title is confusing, let me clarify by example:
 
 We have this protocol with a mutating method:
 
 protocol P { mutating func f(_ x: Int) -> Int }
 
 And a conforming class (which has to conform with a non-mutating method):
 
 class C: P { func f(_ x: Int) -> Int { return x } }
 
 An instance of this class can be used with a let constant:
 
 let c = C()
 c.f(1) // OK
  
 If we make it an existential object conforming to P, the immutability of 
 the method will be erased:
 
 let c: AnyObject & P = C()
 c.f(1) // Cannot use mutating member on immutable value: 'c' is a 'let' 
 constant
 
 A generic context has the same issue:
 
 func f(_ arg: T)-> Int { return arg.f(1) } // Cannot use 
 mutating member on immutable value: ‘arg' is a 'let' constant
 
 My question: 
 
 Is it too much work to preserve method non-mutability in in these cases?
 
 The workaround I am using is this:
 
 protocol Q: class, P { func f(_ x: Int) -> Int } // 'Refine' it to be 
 non-mutating.
 extension C: Q {}
 
 // Now these work:
 let c: Q = C()
 c.f(1) // OK
 func f(_ arg: T)-> Int { return arg.f(1) } // OK
 
 This 

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

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


> On Jan 4, 2018, at 10:49 AM, Jordan Rose  wrote:
> 
> I'll admit I hadn't thought of using "unknown default" (or "default 
> unknown"). I don't think that's terrible, but I mildly prefer `unknown case` 
> because it builds on the "pun" that enum elements are also defined using 
> 'case'. If anything hits this part of the switch, it really will be an 
> "unknown case", i.e. a statically-unknown enum element.
> 
> To Cheyo's point, if this were to be a single token I'd probably spell it 
> #unknown, like #available. Then we'd have `case #unknown:` and something that 
> naturally expands to other pattern positions. I found that less aesthetically 
> pleasing, though, and so a context-sensitive keyword seemed like the way to 
> go.
> 
> (For the record, though, I wouldn't describe `case _` as a special case of 
> `default`. They do exactly the same thing, and `_` is a useful pattern in 
> other contexts, so if anything the current `default` should be thought of as 
> syntactic sugar for `case _`.)

Can case _ be mixed with unknown case? How can we match all compile time known 
cases but exclude future cases? Should be something like `case *` that would 
capture all currently known cases during compile time? case * and case _ would 
be the same in exhaustive enums. 


> 
> I'll add these points to the "Alternatives Considered" section in the PR 
> later today.
> 
> Jordan
> 
> 
>> On Jan 3, 2018, at 22:56, Xiaodi Wu  wrote:
>> 
>> As has already been said, “case unknown” is source-breaking because it 
>> conflicts with any real cases named “unknown”; “\unknown” looks like a key 
>> path but isn’t, and I wonder if it would potentially conflict with existing 
>> key paths.
>> 
>> In any case, my point was not to bikeshed the “unknown” part, but to ask 
>> whether any consideration had been made to have the feature presented as a 
>> flavor of default instead of a flavor of case.
>> 
>>> On Wed, Jan 3, 2018 at 23:57 Cheyo Jimenez  wrote:
>>> 
>>> 
 On Jan 3, 2018, at 6:52 PM, Xiaodi Wu via swift-evolution 
  wrote:
 
 This is a very nice revision. One bikeshedding thought:
 
 Since "unknown case" is presented as a special kind of "default", can't be 
 mixed with "default", and can't be used in case patterns, why not "default 
 unknown" (or "unknown default") instead of "unknown case"?
>>> 
>>> `case _ :` is already a special case of default. 
>>> I’d rather have `case unknown :`
>>> `unknown case :` is weird because of the order of `case`. 
>>> 
>>> Another alternative is `case \unknown :`
>>> `\unknown` would also allow pattern matching. 
>>> 
>>> 
>>> 
 
 
 On Wed, Jan 3, 2018 at 8:05 PM, Jordan Rose via swift-evolution 
  wrote:
>> On Jan 2, 2018, at 18:07, Jordan Rose  wrote:
>> 
>> [Proposal: 
>> https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md]
>> 
>> Whew! Thanks for your feedback, everyone. On the lighter side of 
>> feedback—naming things—it seems that most people seem to like '@frozen', 
>> and that does in fact have the connotations we want it to have. I like 
>> it too.
>> 
>> More seriously, this discussion has convinced me that it's worth 
>> including what the proposal discusses as a 'future' case. The key point 
>> that swayed me is that this can produce a warning when the switch is 
>> missing a case rather than an error, which both provides the necessary 
>> compiler feedback to update your code and allows your dependencies to 
>> continue compiling when you update to a newer SDK. I know people on both 
>> sides won't be 100% satisfied with this, but does it seem like a 
>> reasonable compromise?
>> 
>> The next question is how to spell it. I'm leaning towards `unexpected 
>> case:`, which (a) is backwards-compatible, and (b) also handles "private 
>> cases", either the fake kind that you can do in C (as described in the 
>> proposal), or some real feature we might add to Swift some day. `unknown 
>> case:` isn't bad either.
>> 
>> I too would like to just do `unknown:` or `unexpected:` but that's 
>> technically a source-breaking change:
>> 
>> switch foo {
>> case bar:
>>   unknown:
>>   while baz() {
>> while garply() {
>>   if quux() {
>> break unknown
>>   }
>> }
>>   }
>> }
>> 
>> Another downside of the `unexpected case:` spelling is that it doesn't 
>> work as part of a larger pattern. I don't have a good answer for that 
>> one, but perhaps it's acceptable for now.
>> 
>> I'll write up a revision of the proposal soon and make sure the core 
>> team gets my recommendation when they discuss the results of the review.
>> 
>> ---
>> 
>> 

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

2018-01-04 Thread Xiaodi Wu via swift-evolution
On Thu, Jan 4, 2018 at 13:46 Cheyo Jimenez  wrote:

>
>
> On Jan 4, 2018, at 10:49 AM, Jordan Rose  wrote:
>
> I'll admit I hadn't thought of using "unknown default" (or "default
> unknown"). I don't think that's terrible, but I mildly prefer `unknown
> case` because it builds on the "pun" that enum elements are also defined
> using 'case'. If anything hits this part of the switch, it really will be
> an "unknown case", i.e. a statically-unknown enum element.
>
> To Cheyo's point, if this *were* to be a single token I'd probably spell
> it #unknown, like #available. Then we'd have `case #unknown:` and something
> that naturally expands to other pattern positions. I found that less
> aesthetically pleasing, though, and so a context-sensitive keyword seemed
> like the way to go.
>
> (For the record, though, I wouldn't describe `case _` as a special case of
> `default`. They do exactly the same thing, and `_` is a useful pattern in
> other contexts, so if anything the current `default` should be thought of
> as syntactic sugar for `case _`.)
>
>
> Can case _ be mixed with unknown case? How can we match all compile time
> known cases but exclude future cases?
>

What’s your use case for that? That eliminates the possibility of “unknown
case” giving you compile-time warnings for subsequently added cases, which
was the entire purpose of adding the syntax in the first place.

Should be something like `case *` that would capture all currently known
> cases during compile time? case * and case _ would be the same in
> exhaustive enums.
>
>
>
> I'll add these points to the "Alternatives Considered" section in the PR
> later today.
>
> Jordan
>
>
> On Jan 3, 2018, at 22:56, Xiaodi Wu  wrote:
>
> As has already been said, “case unknown” is source-breaking because it
> conflicts with any real cases named “unknown”; “\unknown” looks like a key
> path but isn’t, and I wonder if it would potentially conflict with existing
> key paths.
>
> In any case, my point was not to bikeshed the “unknown” part, but to ask
> whether any consideration had been made to have the feature presented as a
> flavor of default instead of a flavor of case.
>
> On Wed, Jan 3, 2018 at 23:57 Cheyo Jimenez  wrote:
>
>>
>>
>> On Jan 3, 2018, at 6:52 PM, Xiaodi Wu via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>> This is a very nice revision. One bikeshedding thought:
>>
>> Since "unknown case" is presented as a special kind of "default", can't
>> be mixed with "default", and can't be used in case patterns, why not
>> "default unknown" (or "unknown default") instead of "unknown case"?
>>
>>
>> `case _ :` is already a special case of default.
>> I’d rather have `case unknown :`
>> `unknown case :` is weird because of the order of `case`.
>>
>> Another alternative is `case \unknown :`
>> `\unknown` would also allow pattern matching.
>>
>>
>>
>>
>>
>> On Wed, Jan 3, 2018 at 8:05 PM, Jordan Rose via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>>> On Jan 2, 2018, at 18:07, Jordan Rose  wrote:
>>>
>>> [Proposal:
>>> https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md
>>> ]
>>>
>>> Whew! Thanks for your feedback, everyone. On the lighter side of
>>> feedback—naming things—it seems that most people seem to like '*@frozen*',
>>> and that does in fact have the connotations we want it to have. I like it
>>> too.
>>>
>>> More seriously, this discussion has convinced me that it's worth
>>> including what the proposal discusses as a *'future' case*. The key
>>> point that swayed me is that this can produce a *warning* when the
>>> switch is missing a case rather than an *error,* which both provides
>>> the necessary compiler feedback to update your code and allows your
>>> dependencies to continue compiling when you update to a newer SDK. I know
>>> people on both sides won't be 100% satisfied with this, but does it seem
>>> like a reasonable compromise?
>>>
>>> The next question is how to spell it. I'm leaning towards `unexpected
>>> case:`, which (a) is backwards-compatible, and (b) also handles "private
>>> cases", either the fake kind that you can do in C (as described in the
>>> proposal), or some real feature we might add to Swift some day. `unknown
>>> case:` isn't bad either.
>>>
>>> I too would like to just do `unknown:` or `unexpected:` but that's
>>> technically a source-breaking change:
>>>
>>> switch foo {
>>> case bar:
>>>   unknown:
>>>   while baz() {
>>> while garply() {
>>>   if quux() {
>>> break unknown
>>>   }
>>> }
>>>   }
>>> }
>>>
>>>
>>> Another downside of the `unexpected case:` spelling is that it doesn't
>>> work as part of a larger pattern. I don't have a good answer for that one,
>>> but perhaps it's acceptable for now.
>>>
>>> I'll write up a revision of the proposal soon and make sure the core
>>> team gets my recommendation when 

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

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


> On Jan 4, 2018, at 11:45, Cheyo Jimenez  wrote:
> 
> 
> 
> On Jan 4, 2018, at 10:49 AM, Jordan Rose  > wrote:
> 
>> I'll admit I hadn't thought of using "unknown default" (or "default 
>> unknown"). I don't think that's terrible, but I mildly prefer `unknown case` 
>> because it builds on the "pun" that enum elements are also defined using 
>> 'case'. If anything hits this part of the switch, it really will be an 
>> "unknown case", i.e. a statically-unknown enum element.
>> 
>> To Cheyo's point, if this were to be a single token I'd probably spell it 
>> #unknown, like #available. Then we'd have `case #unknown:` and something 
>> that naturally expands to other pattern positions. I found that less 
>> aesthetically pleasing, though, and so a context-sensitive keyword seemed 
>> like the way to go.
>> 
>> (For the record, though, I wouldn't describe `case _` as a special case of 
>> `default`. They do exactly the same thing, and `_` is a useful pattern in 
>> other contexts, so if anything the current `default` should be thought of as 
>> syntactic sugar for `case _`.)
> 
> Can case _ be mixed with unknown case? How can we match all compile time 
> known cases but exclude future cases? Should be something like `case *` that 
> would capture all currently known cases during compile time? case * and case 
> _ would be the same in exhaustive enums. 

I thought about this, but I couldn’t think of a use case for it. You won’t get 
any exhaustivity checks, and if you recompile the app you silently get 
different behavior. That didn’t seem like a good idea to me.

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


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

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

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

Gwendal

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

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

2018-01-04 Thread Xiaodi Wu via swift-evolution
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? What
do you gain from writing the unknown case first? 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?

If it is inefficient for some reason, the compiler should be free to
> rearrange the order of things, as long as it doesn’t change the outcome.
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


[swift-evolution] Renaming SwiftObject

2018-01-04 Thread Greg Parker via swift-evolution
SwiftObject is an Objective-C class that is the base class of all "pure Swift" 
class types. It needs to be renamed for the Swift stable ABI in order to avoid 
ObjC class name collisions between the stable ABI's Swift runtime and the 
runtime embedded into existing Swift apps.

I suggest `Swift._Object`, mangled as _TtCs7_Object like other Swift ObjC class 
names. 

Any comments?

https://github.com/apple/swift/pull/13748 



-- 
Greg Parker gpar...@apple.com  Runtime 
Wrangler


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


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

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

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

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

Gwendal

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

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

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


> On Jan 4, 2018, at 4:37 PM, Xiaodi Wu  wrote:
> 
> 
> On Thu, Jan 4, 2018 at 19:29 Cheyo J. Jimenez  wrote:
>>> On Jan 4, 2018, at 3:50 PM, Xiaodi Wu  wrote:
>>> 
>>> 
>>> On Thu, Jan 4, 2018 at 18:39 Cheyo J. Jimenez  wrote:
 
> On Jan 4, 2018, at 2:55 PM, Xiaodi Wu  wrote:
> 
> 
> On Thu, Jan 4, 2018 at 17:15 Cheyo J. Jimenez  wrote:
>>> On Jan 4, 2018, at 11:53 AM, Xiaodi Wu  wrote:
>>> 
>>> 
 On Thu, Jan 4, 2018 at 13:46 Cheyo Jimenez  wrote:
 
 
> On Jan 4, 2018, at 10:49 AM, Jordan Rose  
> wrote:
> 
> I'll admit I hadn't thought of using "unknown default" (or "default 
> unknown"). I don't think that's terrible, but I mildly prefer 
> `unknown case` because it builds on the "pun" that enum elements are 
> also defined using 'case'. If anything hits this part of the switch, 
> it really will be an "unknown case", i.e. a statically-unknown enum 
> element.
> 
> To Cheyo's point, if this were to be a single token I'd probably 
> spell it #unknown, like #available. Then we'd have `case #unknown:` 
> and something that naturally expands to other pattern positions. I 
> found that less aesthetically pleasing, though, and so a 
> context-sensitive keyword seemed like the way to go.
> 
> (For the record, though, I wouldn't describe `case _` as a special 
> case of `default`. They do exactly the same thing, and `_` is a 
> useful pattern in other contexts, so if anything the current 
> `default` should be thought of as syntactic sugar for `case _`.)
 
 Can case _ be mixed with unknown case? How can we match all compile 
 time known cases but exclude future cases?
>>> 
>>> What’s your use case for that? That eliminates the possibility of 
>>> “unknown case” giving you compile-time warnings for subsequently added 
>>> cases, which was the entire purpose of adding the syntax in the first 
>>> place.
>> 
>> I was thinking of a generalized `unknown case` pattern but that is out 
>> of scope for this proposal. 
>> 
>> switch excuse {
>>  case .eatenByPet :
>>//…
>>  unknown case:
>>// …
>>  case _:
>>// …
>>  }
>> 
>>> 
 Should there be something like `case *` that would capture all 
 currently known cases during compile time? case * and case _ would be 
 the same in exhaustive enums. 
>> 
>> This is why I was suggesting another pattern that only captures known 
>> cases at compile time:
>> 
>> switch excuse {
>>  case .eatenByPet :
>>//…
>>  case * : //  All cases captured at compile time. 
>>// …
>>  unknown case:
>>// …
>>  }
> 
> Sorry, I don’t understand. However you spell it, what is your use case 
> for this? The stated purpose of “unknown case” is to gain compile-time 
> exhaustiveness testing, but this would not allow for that.
 
 
 
 
 switch (excuse, notifiedTeacherBeforeDeadline) {
 case (.eatenByPet, true):
   // …
 case (.thoughtItWasDueNextWeek, true):
   // …
 case (unknown case, true):
   // …
 case (_, false):
   // …
 }
 
 Im referring to the future direction section in the new PR. The above 
 example if from there. 
 
 I am fine with `unknown case` being required to be at the end of the 
 switch for now. 
 
 I think of `unknown case` as a pattern that only matches unknown cases no 
 matter where on the switch it is.
 
 This is why I do not think that `default unknown` would work well once 
 `unknown case` can be used a pattern.
 
 We can start a new thread on this if you’d like. 
>>> 
>>> The reason I put forward “default unknown” is precisely because the 
>>> proposed feature *cannot* be used in a pattern and therefore seems more apt 
>>> as not a case.
>>> 
>> 
>> It can not be used in a pattern now but you could in the future if left as 
>> `case`. 
>> 
>> 
>>> It actually makes it more natural to use in the given example above because 
>>> “default unknown” could actually be used to provide compile-time 
>>> exhaustiveness checking for such a tuple pattern, whereas without being 
>>> able to use “unknown case” in a pattern you can’t write “case (unknown 
>>> case, _)”.
>> 
>> The way `unknown case` enforces  compile-time exhaustiveness is by only 
>> matching unknown cases. The implementation may be more close to default by 
>> the virtue of being forced to go at the end of the switch statement now but 
>> that should not dictate the user experience. 
> 
> We seem to 

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

2018-01-04 Thread Xiaodi Wu via swift-evolution
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:
>
>> On Jan 4, 2018, at 3:50 PM, Xiaodi Wu  wrote:
>>
>>
>> On Thu, Jan 4, 2018 at 18:39 Cheyo J. Jimenez 
>> wrote:
>>
>>>
>>> On Jan 4, 2018, at 2:55 PM, Xiaodi Wu  wrote:
>>>
>>>
>>> On Thu, Jan 4, 2018 at 17:15 Cheyo J. Jimenez 
>>> wrote:
>>>
 On Jan 4, 2018, at 11:53 AM, Xiaodi Wu  wrote:


 On Thu, Jan 4, 2018 at 13:46 Cheyo Jimenez  wrote:

>
>
> On Jan 4, 2018, at 10:49 AM, Jordan Rose 
> wrote:
>
> I'll admit I hadn't thought of using "unknown default" (or "default
> unknown"). I don't think that's terrible, but I mildly prefer `unknown
> case` because it builds on the "pun" that enum elements are also defined
> using 'case'. If anything hits this part of the switch, it really will be
> an "unknown case", i.e. a statically-unknown enum element.
>
> To Cheyo's point, if this *were* to be a single token I'd probably
> spell it #unknown, like #available. Then we'd have `case #unknown:` and
> something that naturally expands to other pattern positions. I found that
> less aesthetically pleasing, though, and so a context-sensitive keyword
> seemed like the way to go.
>
> (For the record, though, I wouldn't describe `case _` as a special
> case of `default`. They do exactly the same thing, and `_` is a useful
> pattern in other contexts, so if anything the current `default` should be
> thought of as syntactic sugar for `case _`.)
>
>
> Can case _ be mixed with unknown case? How can we match all compile
> time known cases but exclude future cases?
>

 What’s your use case for that? That eliminates the possibility of
 “unknown case” giving you compile-time warnings for subsequently added
 cases, which was the entire purpose of adding the syntax in the first 
 place.


 I was thinking of a generalized `unknown case` pattern but that is out
 of scope for this proposal.
 


 switch excuse {
  case .eatenByPet :
//…
  unknown case:
// …
  case _:
// …
  }


 Should there be something like `case *` that would capture all
> currently known cases during compile time? case * and case _ would be the
> same in exhaustive enums.
>

 This is why I was suggesting another pattern that only captures known
 cases at compile time:

 switch excuse {
  case .eatenByPet :
//…
  case * : //  All cases captured at compile time.
// …
  unknown case:
// …
  }

>>>
>>> Sorry, I don’t understand. However you spell it, what is your use case
>>> for this? The stated purpose of “unknown case” is to gain compile-time
>>> exhaustiveness testing, but this would not allow for that.
>>>
>>>
>>>
>>>
>>>
>>> switch (excuse, notifiedTeacherBeforeDeadline) {case (.eatenByPet, true):
>>>   // …case (.thoughtItWasDueNextWeek, true):
>>>   // …case (unknown case, true):
>>>   // …case (_, false):
>>>   // …}
>>>
>>>
>>> Im referring to the future direction section in the new PR
>>> .
>>> The above example if from there.
>>>
>>> I am fine with `unknown case` being required to be at the end of the
>>> switch for now.
>>>
>>> I think of `unknown case` as a pattern that only matches unknown cases
>>> no matter where on the switch it is.
>>>
>>> This is why I do not think that `default unknown` would work well once
>>> `unknown case` can be used a pattern.
>>>
>>> We can start a new thread on this if you’d like.
>>>
>>
>> The reason I put forward “default unknown” is precisely because the
>> proposed feature *cannot* be used in a pattern and therefore seems more apt
>> as not a case.
>>
>> It can not be used in a pattern now but you could in the future if left
>> as `case`.
>>
>>
>> It actually makes it more natural to use in the given example above
>> because “default unknown” could actually be used to provide compile-time
>> exhaustiveness checking for such a tuple pattern, whereas without being
>> able to use “unknown case” in a pattern you can’t write “case (unknown
>> case, _)”.
>>
>>
>> The way `unknown case` enforces  compile-time exhaustiveness is by only
>> matching unknown cases. The implementation may be more close to default by
>> the virtue of being forced to go at the end of the switch statement now but
>> that should not 

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

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

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

If it is inefficient for some reason, the compiler should be free to rearrange 
the order of things, as long as it doesn’t change the outcome.

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


Re: [swift-evolution] Renaming SwiftObject

2018-01-04 Thread Félix Cloutier via swift-evolution
I'll bite. Shouldn't that name encode that it's an Objective-C object? Like 
Swift.ObjCBase?

> Le 4 janv. 2018 à 22:10, Greg Parker via swift-evolution 
>  a écrit :
> 
> SwiftObject is an Objective-C class that is the base class of all "pure 
> Swift" class types. It needs to be renamed for the Swift stable ABI in order 
> to avoid ObjC class name collisions between the stable ABI's Swift runtime 
> and the runtime embedded into existing Swift apps.
> 
> I suggest `Swift._Object`, mangled as _TtCs7_Object like other Swift ObjC 
> class names. 
> 
> Any comments?
> 
> https://github.com/apple/swift/pull/13748 
> 
> 
> 
> -- 
> Greg Parker gpar...@apple.com  Runtime 
> Wrangler
> 
> 
> ___
> 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] Renaming SwiftObject

2018-01-04 Thread Xiaodi Wu via swift-evolution
If it’s the base class for all Swift class types, I think “SwiftObject” is
ideal and the proposed renaming is sensible. What does it matter that it’s
an Obj-C object? Why does that have to be in the name? Let’s not bikeshed
this and keep it simple.

On Thu, Jan 4, 2018 at 22:21 Félix Cloutier via swift-evolution <
swift-evolution@swift.org> wrote:

> I'll bite. Shouldn't that name encode that it's an Objective-C object?
> Like Swift.ObjCBase?
>
>
> Le 4 janv. 2018 à 22:10, Greg Parker via swift-evolution <
> swift-evolution@swift.org> a écrit :
>
> SwiftObject is an Objective-C class that is the base class of all "pure
> Swift" class types. It needs to be renamed for the Swift stable ABI in
> order to avoid ObjC class name collisions between the stable ABI's Swift
> runtime and the runtime embedded into existing Swift apps.
>
> I suggest `Swift._Object`, mangled as _TtCs7_Object like other Swift ObjC
> class names.
>
> Any comments?
>
> https://github.com/apple/swift/pull/13748
>
>
> --
> Greg Parker gpar...@apple.com Runtime Wrangler
>
>
> ___
> 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-04 Thread Brent Royal-Gordon via swift-evolution
> On Jan 3, 2018, at 10:02 AM, Dave DeLong via swift-evolution 
>  wrote:
> 
> 1️⃣ a @frozen/@tangled/@moana attribute for enums that’s only consulted on 
> externally-linked modules


Naming is serious business, Dave. Let it go.

*ducks*

-- 
Brent Royal-Gordon
Architechies

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