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

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


Sent from my iPhone

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


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

2018-01-02 Thread Goffredo Marocchi via swift-evolution
This is not what I am saying.

Change X helps use case A, but unnecessarily removes feature important (and 
like argument labels for everything quite Swift defining, but alas...) for use 
case B.

What I am saying is that before merging change X we should figure out what is 
needed (change Y) to ensure that use case B is not harmed while we do also help 
use case A.

Use case A being binary frameworks shipped by the OS and use case B being 
everything else... :).

Change X being the current proposal.

Change Y being the feature(s) needed to be added to X to ensure X’ helps use 
case A without removing the functionality use case B relies on.

Sent from my iPhone

> On 3 Jan 2018, at 02:01, Xiaodi Wu  wrote:
> 
>> On Tue, Jan 2, 2018 at 7:02 PM, Goffredo Marocchi  wrote:
>> 
>>> On 3 Jan 2018, at 00:38, Xiaodi Wu via swift-evolution 
>>>  wrote:
>>> 
 On Tue, Jan 2, 2018 at 4:31 PM, Jonathan Hull  wrote:
 I think there are a couple of different definitions running around, and 
 that is confusing things.
 
 In my mind, ‘unexpected:’ catches only cases which were unknown at compile 
 time. Adding cases to an enum *should* be a source-breaking change. That 
 is the whole point of this.  We should have to update the switch (either 
 by handling new case explicitly, or by adding default) before successfully 
 compiling.  What ‘unexpected:’ protects against are changes to a linked 
 binary (e.g. iOS) that are now vending cases we didn’t know about when we 
 were compiled.
 
 I’ll say it again… framing this idea as one of exhaustiveness is really 
 confusing.  Enums should just always be exhaustive in swift.  There may be 
 cases where we need to use ‘unexpected:’ to handle unexpected/future cases 
 exhaustively.  If we annotate an enum as @frozen, then we won’t need to do 
 that to be exhaustive because we know it won’t change out from under us.  
 Always exhaustive. Much less confusing…
 
 Thanks,
 Jon
>>> 
>>> I think, then, you fundamentally disagree with the starting premise of the 
>>> proposal, which is specifically the addition of nonexhaustive enums to the 
>>> language, and making them the default sort of enum so that adding cases *is 
>>> not* a source-breaking change. If your whole purpose is to change the 
>>> proposal so that adding cases will _always_ be a source-breaking change and 
>>> enums are _never_ nonexhaustive, then I'm not sure how to proceed in the 
>>> discussion as we're working towards diametrically opposite goals.
>> 
>> The main issue is a resilience issue and it mainly affects binary frameworks 
>> the app links with at runtime and does not package them (read mostly Apple 
>> ones for the moment)... the fact that enum changes are source breaking is 
>> the whole entire point of swift’s enum and a best practice warning to always 
>> have turned on even before with Objective-C. Our goal, and yours goal should 
>> be the one and the same too IMHO, is not to throw the proverbial baby out 
>> with the bath water.
>> 
>> We should look for a solution that allows what Apple and OS framework 
>> authors need and also what is best for app developers and if we need 
>> something to do this we pause this proposal until that something is ready 
>> and merged.
>> 
> 
> Hmm, I think indeed we disagree fundamentally on what this proposal is about, 
> or the desired end goal.
> 
> If I understand correctly, *your* end goal is simply to enable something like 
> `@_fixed_layout` for enums, an optimization hint to allow binary frameworks 
> to add cases without being shipped with apps. You want no semantic changes to 
> how enums work.
> 
> *My* understand of this proposals goal--and I support it--is that it takes 
> this ABI compatibility problem as a starting point and discovers that there 
> are fundamentally two semantic categories of enums, ones that are necessarily 
> exhaustive (there's either something or nothing for an Optional value, there 
> are three possible comparison results for comparable types, there are four 
> sides to a rectangular window, etc.) and ones that are not. It discovers 
> that, empirically, most enums are nonexhaustive, and proposes changes to the 
> grammar so that Swift distinguishes between these two so as to prompt 
> developers to deal with the issue of nonexhaustiveness where the semantics 
> require it. The goal, then, is to introduce new spellings and semantics to 
> distinguish between two different flavors of enum. Like `open` vs. `public` 
> for classes, this has implications for ABI compatibility but isn't just about 
> ABI compatibility.
> 
> I was laboring under the idea that we were working to make such a 
> wide-ranging change as ergonomic as possible, but it seems like you and Jon 
> do not want such a change at all.
> 
>>> 
> On Jan 2, 2018, at 1:41 PM, Xiaodi Wu via swift-evolution 

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

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

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

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

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

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

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

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

Possible solutions include:

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

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

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

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

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

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

-- Howard. 

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

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

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

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

+1 to “@tangled” because abi is complicated


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

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


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

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

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


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

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

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

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


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

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

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

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

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


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

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

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

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

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

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


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

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

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

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

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

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


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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

Happy new year to you as well!

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

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

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

>
> On Jan 2, 2018, at 3:41 PM, Xiaodi Wu  wrote:
>
> On Tue, Jan 2, 2018 at 3:27 PM, Kevin Nattinger 
> wrote:
>
>> [...]
>>
>> in what other circumstances do we insist that the compiler inform the end
>>> user about future additions to the API at compile time?
>>>
>>>
>>> This isn’t a request for the compiler to inform the user about future
>>> additions to an API.  It is a request to validate the compiler’s knowledge
>>> of the *current* state of an API with the *current* state of the source
>>> code.
>>>
>>
>> Well, it's of course impossible to inform the user about future
>> additions, so that's poorly phrased on my part. It's about the compiler
>> informing the end user about *new* additions, part of the *current* state
>> of the API, that have cropped up since the user last revised the code when
>> the API was in a *previous* state (or, indistinguishably, members of which
>> a user is unaware regardless of the temporal sequence of when such members
>> were added). In what other circumstances do we insist that the compiler
>> perform this service?
>>
>>
>> Enums. That's literally how they work today. You are arguing in favor of
>> actively removing compiler-aided correctness.
>>
>> There's also protocol requirements
>>
>
> No, that's now how enums work today, and it's not how protocol
> requirements work today. Enums today are all semantically exhaustive; if a
> case is added in a later version of a library, it's semantically a
> *different* enum type that happens to share the same name. Not considering
> all the cases of an exhaustive enum is an _error_, not a _warning_, because
> there is no basis on which to proceed. This will not change with the
> proposal. Likewise, adding a protocol requirement without a default
> implementation is source-breaking. The result is a compiler _error_.
>
> The question is, what non-source breaking API additions today cause the
> compiler to inform the end user of such additions?
>
>
> Posing the question this way takes it as a given that adding a case to a
> resilient enum is non-source breaking with a full stop.
>

Ah, yes. As I wrote in an earlier email in reply to Jon and others, it
seems we have a fundamental difference here. I take it as a given, full
stop, that this is what we are setting out to do. If it is not, then we are
trying to design with different end goals in mind.

The position of everyone asking for something like `future` / `unknown` as
> an alternative to `default` is exactly that this should not be the case.
> Instead, adding a case should always be binary compatible and should be
> source compatible by default, but authors should have the ability to opt-in
> to making case additions be source-breaking for individual switch
> statements.
>
> When you view it this way we are not asking the compiler to inform us of a
> non-source breaking addition.  We are asking the compiler to treat an
> addition as source breaking in a specific context.
>
> The answer is: none whatsoever. Not new methods or properties on a type,
> not even new protocol requirements that have a default implementation.
>
>
> and, arguably, deprecated methods with a proper message ("use foo
>> instead").
>>
>
>
>
>
>
___
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-02 Thread Matthew Johnson via swift-evolution

> On Jan 2, 2018, at 2:09 PM, Xiaodi Wu  wrote:
> 
> On Tue, Jan 2, 2018 at 1:46 PM, Matthew Johnson  > wrote:
> 
> 
> Sent from my iPad
> 
> On Jan 2, 2018, at 12:48 PM, Xiaodi Wu  > wrote:
> 
>> On Tue, Jan 2, 2018 at 9:38 AM, Matthew Johnson via swift-evolution 
>> > wrote:
>> 
>> 
>> Sent from my iPad
>> 
>> On Jan 1, 2018, at 11:47 PM, Chris Lattner > > wrote:
>> 
 On Dec 31, 2017, at 12:14 PM, Matthew Johnson via swift-evolution 
 > wrote:
 
 I agree that we need a solution to the problem described.  I also agree 
 that non-exhaustive is most in keeping with the overall design of Swift at 
 module boundaries.  However, I believe this proposal should be modified 
 before being accepted
>>> 
>>> Thanks for writing this up - you’ve explained a common concern in an 
>>> interesting way:
>>> 
 This is likely to be a relatively rare need mostly encountered by 3rd 
 party libraries but it will happen.  When it does happen it would be 
 really unfortunate to be forced to use a `default` clause rather than 
 something like a `future` clause which will produce an error when compiled 
 against an SDK where the enum includes cases that are not covered.  I can 
 imagine cases where this catch-all case would need to do something other 
 than abort the program so I do not like the `switch!` suggestion that has 
 been discussed.  The programmer should still be responsible for 
 determining the behavior of unknown cases.
>>> ..
 While library authors have a legitimate need to reserve the right to 
 introduce new cases for some enums this need can be met without taking 
 away a useful tool for generating static compiler errors when code does 
 not align with intent (in this case, the intent being to cover all known 
 cases).  Switch statements working with these kinds of enums should be 
 required to cover unknown cases but should be able to do so while still 
 being statically checked with regards to known cases.  
>>> 
>>> I think that this could be the crux of some major confusion, the root of 
>>> which is the difference between source packages and binary packages that 
>>> are updated outside your control (e.g. the OS, or a dynamic library that is 
>>> updated independently of your app like a 3rd party plugin).  Consider:
>>> 
>>> 1) When dealing with independently updated binary packages, your code *has* 
>>> to implement some behavior for unexpected cases if the enum is 
>>> non-exhaustive.  It isn’t acceptable to not handle that case, and it isn’t 
>>> acceptable to abort because then your app will start crashing when a new OS 
>>> comes out. You have to build some sort of fallback into your app.
>>> 
>>> 2) When dealing with a source package that contributes to your app (e.g. 
>>> through SwiftPM), *YOU* control when you update that package, and therefore 
>>> it is entirely reasonable to exhaustively handle enums even if that package 
>>> owner didn’t “intend” for them to be exhaustive.  When *you* chose to 
>>> update the package, you get the “unhandled case” error, and you have 
>>> maximal “knowability” about the package’s behavior.
>>> 
>>> 
>>> It seems that your concern stems from the fact that the feature as proposed 
>>> is aligned around module boundaries, and therefore overly punishes source 
>>> packages like #2.  I hope you agree that in case #1, that the feature as 
>>> proposed is the right and only thing we can do: you really do have to 
>>> handle unknown future cases somehow.
>>> 
>>> If I’m getting this right, then maybe there is a variant of the proposal 
>>> that ties the error/warning behavior to whether or not a module is a source 
>>> module vs a binary module.  The problem with that right now is that we have 
>>> no infrastructure in the language to know this…
>> 
>> Hi Chris, thanks for your reply.
>> 
>> The concern you describe isn’t exactly what I was describing but it is 
>> related.  John McCall recently posted a sketch of a solution to the concern 
>> you describe which looked great to me.  I don’t have time to look up the 
>> link this morning but I think it was in this review thread.
>> 
>> The actual concern I am describing is where a 3rd party library (or app) 
>> wants to switch over a non-exhaustive enum provided by a module that is a 
>> binary (not source) dependency.  The author of the 3rd party library may 
>> have a legitimate reason to switch over an enum despite the author of the 
>> binary module reserving the right to add additional cases.  
>> 
>> When this circumstance arises they will do it using the tools provided by 
>> the language.  Regardless of the final language 

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

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

> On Jan 2, 2018, at 3:41 PM, Xiaodi Wu  wrote:
> 
> On Tue, Jan 2, 2018 at 3:27 PM, Kevin Nattinger  > wrote:
> [...]
> 
>>> in what other circumstances do we insist that the compiler inform the end 
>>> user about future additions to the API at compile time?
>> 
>> This isn’t a request for the compiler to inform the user about future 
>> additions to an API.  It is a request to validate the compiler’s knowledge 
>> of the current state of an API with the current state of the source code. 
>> 
>> Well, it's of course impossible to inform the user about future additions, 
>> so that's poorly phrased on my part. It's about the compiler informing the 
>> end user about *new* additions, part of the *current* state of the API, that 
>> have cropped up since the user last revised the code when the API was in a 
>> *previous* state (or, indistinguishably, members of which a user is unaware 
>> regardless of the temporal sequence of when such members were added). In 
>> what other circumstances do we insist that the compiler perform this service?
> 
> Enums. That's literally how they work today. You are arguing in favor of 
> actively removing compiler-aided correctness.
> 
> There's also protocol requirements
> 
> No, that's now how enums work today, and it's not how protocol requirements 
> work today. Enums today are all semantically exhaustive; if a case is added 
> in a later version of a library, it's semantically a *different* enum type 
> that happens to share the same name. Not considering all the cases of an 
> exhaustive enum is an _error_, not a _warning_, because there is no basis on 
> which to proceed. This will not change with the proposal. Likewise, adding a 
> protocol requirement without a default implementation is source-breaking. The 
> result is a compiler _error_.
> 
> The question is, what non-source breaking API additions today cause the 
> compiler to inform the end user of such additions?

Posing the question this way takes it as a given that adding a case to a 
resilient enum is non-source breaking with a full stop.  The position of 
everyone asking for something like `future` / `unknown` as an alternative to 
`default` is exactly that this should not be the case.  Instead, adding a case 
should always be binary compatible and should be source compatible by default, 
but authors should have the ability to opt-in to making case additions be 
source-breaking for individual switch statements.  

When you view it this way we are not asking the compiler to inform us of a 
non-source breaking addition.  We are asking the compiler to treat an addition 
as source breaking in a specific context.

> The answer is: none whatsoever. Not new methods or properties on a type, not 
> even new protocol requirements that have a default implementation.
> 
> 
> and, arguably, deprecated methods with a proper message ("use foo instead").
> 
> 



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


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

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

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

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

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

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

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

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

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

---

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

Jordan

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


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

2018-01-02 Thread Xiaodi Wu via swift-evolution
On Tue, Jan 2, 2018 at 7:02 PM, Goffredo Marocchi  wrote:

>
> On 3 Jan 2018, at 00:38, Xiaodi Wu via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> On Tue, Jan 2, 2018 at 4:31 PM, Jonathan Hull  wrote:
>
>> I think there are a couple of different definitions running around, and
>> that is confusing things.
>>
>> In my mind, ‘unexpected:’ catches only cases which were unknown at
>> compile time. Adding cases to an enum *should* be a source-breaking change.
>> That is the whole point of this.  We should have to update the switch
>> (either by handling new case explicitly, or by adding default) before
>> successfully compiling.  What ‘unexpected:’ protects against are changes to
>> a linked binary (e.g. iOS) that are now vending cases we didn’t know about
>> when we were compiled.
>>
>> I’ll say it again… framing this idea as one of exhaustiveness is really
>> confusing.  Enums should just always be exhaustive in swift.  There may be
>> cases where we need to use ‘unexpected:’ to handle unexpected/future cases
>> exhaustively.  If we annotate an enum as @frozen, then we won’t need to do
>> that to be exhaustive because we know it won’t change out from under us.
>> Always exhaustive. Much less confusing…
>>
>> Thanks,
>> Jon
>>
>
> I think, then, you fundamentally disagree with the starting premise of the
> proposal, which is specifically the addition of nonexhaustive enums to the
> language, and making them the default sort of enum so that adding cases *is
> not* a source-breaking change. If your whole purpose is to change the
> proposal so that adding cases will _always_ be a source-breaking change and
> enums are _never_ nonexhaustive, then I'm not sure how to proceed in the
> discussion as we're working towards diametrically opposite goals.
>
>
> The main issue is a resilience issue and it mainly affects binary
> frameworks the app links with at runtime and does not package them (read
> mostly Apple ones for the moment)... the fact that enum changes are source
> breaking is the whole entire point of swift’s enum and a best practice
> warning to always have turned on even before with Objective-C. Our goal,
> and yours goal should be the one and the same too IMHO, is not to throw the
> proverbial baby out with the bath water.
>
> We should look for a solution that allows what Apple and OS framework
> authors need and also what is best for app developers and if we need
> something to do this we pause this proposal until that something is ready
> and merged.
>
>
Hmm, I think indeed we disagree fundamentally on what this proposal is
about, or the desired end goal.

If I understand correctly, *your* end goal is simply to enable something
like `@_fixed_layout` for enums, an optimization hint to allow binary
frameworks to add cases without being shipped with apps. You want no
semantic changes to how enums work.

*My* understand of this proposals goal--and I support it--is that it takes
this ABI compatibility problem as a starting point and discovers that there
are fundamentally two semantic categories of enums, ones that are
necessarily exhaustive (there's either something or nothing for an Optional
value, there are three possible comparison results for comparable types,
there are four sides to a rectangular window, etc.) and ones that are not.
It discovers that, empirically, most enums are nonexhaustive, and proposes
changes to the grammar so that Swift distinguishes between these two so as
to prompt developers to deal with the issue of nonexhaustiveness where the
semantics require it. The goal, then, is to introduce new spellings and
semantics to distinguish between two different flavors of enum. Like `open`
vs. `public` for classes, this has implications for ABI compatibility but
isn't just about ABI compatibility.

I was laboring under the idea that we were working to make such a
wide-ranging change as ergonomic as possible, but it seems like you and Jon
do not want such a change at all.


> On Jan 2, 2018, at 1:41 PM, Xiaodi Wu via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>> On Tue, Jan 2, 2018 at 3:27 PM, Kevin Nattinger 
>> wrote:
>>
>>> [...]
>>>
>>> in what other circumstances do we insist that the compiler inform the
 end user about future additions to the API at compile time?


 This isn’t a request for the compiler to inform the user about future
 additions to an API.  It is a request to validate the compiler’s knowledge
 of the *current* state of an API with the *current* state of the
 source code.

>>>
>>> Well, it's of course impossible to inform the user about future
>>> additions, so that's poorly phrased on my part. It's about the compiler
>>> informing the end user about *new* additions, part of the *current* state
>>> of the API, that have cropped up since the user last revised the code when
>>> the API was in a *previous* state (or, indistinguishably, members of which
>>> a 

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

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

> On 3 Jan 2018, at 00:38, Xiaodi Wu via swift-evolution 
>  wrote:
> 
>> On Tue, Jan 2, 2018 at 4:31 PM, Jonathan Hull  wrote:
>> I think there are a couple of different definitions running around, and that 
>> is confusing things.
>> 
>> In my mind, ‘unexpected:’ catches only cases which were unknown at compile 
>> time. Adding cases to an enum *should* be a source-breaking change. That is 
>> the whole point of this.  We should have to update the switch (either by 
>> handling new case explicitly, or by adding default) before successfully 
>> compiling.  What ‘unexpected:’ protects against are changes to a linked 
>> binary (e.g. iOS) that are now vending cases we didn’t know about when we 
>> were compiled.
>> 
>> I’ll say it again… framing this idea as one of exhaustiveness is really 
>> confusing.  Enums should just always be exhaustive in swift.  There may be 
>> cases where we need to use ‘unexpected:’ to handle unexpected/future cases 
>> exhaustively.  If we annotate an enum as @frozen, then we won’t need to do 
>> that to be exhaustive because we know it won’t change out from under us.  
>> Always exhaustive. Much less confusing…
>> 
>> Thanks,
>> Jon
> 
> I think, then, you fundamentally disagree with the starting premise of the 
> proposal, which is specifically the addition of nonexhaustive enums to the 
> language, and making them the default sort of enum so that adding cases *is 
> not* a source-breaking change. If your whole purpose is to change the 
> proposal so that adding cases will _always_ be a source-breaking change and 
> enums are _never_ nonexhaustive, then I'm not sure how to proceed in the 
> discussion as we're working towards diametrically opposite goals.

The main issue is a resilience issue and it mainly affects binary frameworks 
the app links with at runtime and does not package them (read mostly Apple ones 
for the moment)... the fact that enum changes are source breaking is the whole 
entire point of swift’s enum and a best practice warning to always have turned 
on even before with Objective-C. Our goal, and yours goal should be the one and 
the same too IMHO, is not to throw the proverbial baby out with the bath water.

We should look for a solution that allows what Apple and OS framework authors 
need and also what is best for app developers and if we need something to do 
this we pause this proposal until that something is ready and merged.

> 
>>> On Jan 2, 2018, at 1:41 PM, Xiaodi Wu via swift-evolution 
>>>  wrote:
>>> 
 On Tue, Jan 2, 2018 at 3:27 PM, Kevin Nattinger  
 wrote:
 [...]
 
>>> in what other circumstances do we insist that the compiler inform the 
>>> end user about future additions to the API at compile time?
>> 
>> This isn’t a request for the compiler to inform the user about future 
>> additions to an API.  It is a request to validate the compiler’s 
>> knowledge of the current state of an API with the current state of the 
>> source code. 
> 
> Well, it's of course impossible to inform the user about future 
> additions, so that's poorly phrased on my part. It's about the compiler 
> informing the end user about *new* additions, part of the *current* state 
> of the API, that have cropped up since the user last revised the code 
> when the API was in a *previous* state (or, indistinguishably, members of 
> which a user is unaware regardless of the temporal sequence of when such 
> members were added). In what other circumstances do we insist that the 
> compiler perform this service?
 
 Enums. That's literally how they work today. You are arguing in favor of 
 actively removing compiler-aided correctness.
 
 There's also protocol requirements
>>> 
>>> No, that's now how enums work today, and it's not how protocol requirements 
>>> work today. Enums today are all semantically exhaustive; if a case is added 
>>> in a later version of a library, it's semantically a *different* enum type 
>>> that happens to share the same name. Not considering all the cases of an 
>>> exhaustive enum is an _error_, not a _warning_, because there is no basis 
>>> on which to proceed. This will not change with the proposal. Likewise, 
>>> adding a protocol requirement without a default implementation is 
>>> source-breaking. The result is a compiler _error_.
>>> 
>>> The question is, what non-source breaking API additions today cause the 
>>> compiler to inform the end user of such additions? The answer is: none 
>>> whatsoever. Not new methods or properties on a type, not even new protocol 
>>> requirements that have a default implementation.
>>> 
>>> 
 and, arguably, deprecated methods with a proper message ("use foo 
 instead").
>>> 
>>> 
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> 

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

2018-01-02 Thread Xiaodi Wu via swift-evolution
On Tue, Jan 2, 2018 at 4:31 PM, Jonathan Hull  wrote:

> I think there are a couple of different definitions running around, and
> that is confusing things.
>
> In my mind, ‘unexpected:’ catches only cases which were unknown at compile
> time. Adding cases to an enum *should* be a source-breaking change. That is
> the whole point of this.  We should have to update the switch (either by
> handling new case explicitly, or by adding default) before successfully
> compiling.  What ‘unexpected:’ protects against are changes to a linked
> binary (e.g. iOS) that are now vending cases we didn’t know about when we
> were compiled.
>
> I’ll say it again… framing this idea as one of exhaustiveness is really
> confusing.  Enums should just always be exhaustive in swift.  There may be
> cases where we need to use ‘unexpected:’ to handle unexpected/future cases
> exhaustively.  If we annotate an enum as @frozen, then we won’t need to do
> that to be exhaustive because we know it won’t change out from under us.
> Always exhaustive. Much less confusing…
>
> Thanks,
> Jon
>

I think, then, you fundamentally disagree with the starting premise of the
proposal, which is specifically the addition of nonexhaustive enums to the
language, and making them the default sort of enum so that adding cases *is
not* a source-breaking change. If your whole purpose is to change the
proposal so that adding cases will _always_ be a source-breaking change and
enums are _never_ nonexhaustive, then I'm not sure how to proceed in the
discussion as we're working towards diametrically opposite goals.

On Jan 2, 2018, at 1:41 PM, Xiaodi Wu via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> On Tue, Jan 2, 2018 at 3:27 PM, Kevin Nattinger 
> wrote:
>
>> [...]
>>
>> in what other circumstances do we insist that the compiler inform the end
>>> user about future additions to the API at compile time?
>>>
>>>
>>> This isn’t a request for the compiler to inform the user about future
>>> additions to an API.  It is a request to validate the compiler’s knowledge
>>> of the *current* state of an API with the *current* state of the source
>>> code.
>>>
>>
>> Well, it's of course impossible to inform the user about future
>> additions, so that's poorly phrased on my part. It's about the compiler
>> informing the end user about *new* additions, part of the *current* state
>> of the API, that have cropped up since the user last revised the code when
>> the API was in a *previous* state (or, indistinguishably, members of which
>> a user is unaware regardless of the temporal sequence of when such members
>> were added). In what other circumstances do we insist that the compiler
>> perform this service?
>>
>>
>> Enums. That's literally how they work today. You are arguing in favor of
>> actively removing compiler-aided correctness.
>>
>> There's also protocol requirements
>>
>
> No, that's now how enums work today, and it's not how protocol
> requirements work today. Enums today are all semantically exhaustive; if a
> case is added in a later version of a library, it's semantically a
> *different* enum type that happens to share the same name. Not considering
> all the cases of an exhaustive enum is an _error_, not a _warning_, because
> there is no basis on which to proceed. This will not change with the
> proposal. Likewise, adding a protocol requirement without a default
> implementation is source-breaking. The result is a compiler _error_.
>
> The question is, what non-source breaking API additions today cause the
> compiler to inform the end user of such additions? The answer is: none
> whatsoever. Not new methods or properties on a type, not even new protocol
> requirements that have a default implementation.
>
>
> and, arguably, deprecated methods with a proper message ("use foo
>> instead").
>>
>
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2018-01-02 Thread Eneko Alonso via swift-evolution
In regards of A, doesn’t this code cover al cases?

@incomplete enum {
  case pancake
  case waffle
  case juice
}

When the @incomplete tag is present, the compiler enforces (with an error) that 
all switches handle a default case:

switch breakfast {
  case .pancake:
  case .waffle:
  case .juice:
  default:  // <— default case must be present to compile
break
}

This is also allowed:

switch breakfast {
  case .pancake:
// only like pancakes and nothing else!
  default:  // <— default case must be present to compile
break
}

I think it is safe for the compiler not to warn users when new cases are 
introduced (by the new OS, for instance), in similar way as users are not 
warned when new methods are added to a class, or new classes added to a 
framework. For instance, if a new case is added for UILabel text alignment, I 
don’t _really_ need to know unless I wanted my app to support that case. Users 
would be able to get that information from the documentation.

In regards of B (select one of the choices to be chosen as the normal choice if 
no choice is made by the user), sounds like an edge case and should be left for 
a separate proposal.


Thank you,
Eneko


> On Jan 2, 2018, at 10:11 AM, Jason Merchant via swift-evolution 
>  wrote:
> 
> I think this whole thing has been unnecessarily convoluted. As a result, the 
> majority of the replies are rabbit holes.
> 
> In my opinion, the true root of the concept in question is as follows:
> 
> A list of something is desired:
> 1 - Pancake
> 2 - Waffle
> 3 - Juice
> 
> Developer wishes to be able to:
> A) Add new things to the list of choices in the future as they come up with 
> new ideas
> B) Sometimes select one of the choices to be chosen as the normal choice if 
> no choice is made by the user
> 
> A and B are separate desires. In some circumstances a developer may want to 
> add a new choice and make it the normal choice when there was no normal 
> choice was clarified before.
> 
> 
> 
> Part 2:
> 
> After this simple desire is clear, there should be two discussions:
> A) In a text only coding language, what would we like the syntax to look 
> like? (Without regard to past-bias. What should it really be, forget what 
> mistaken design choices were made in Swift in the past)
> B) How do we approach making this happen behind the scenes?
> 
> Bonus: Given that some of us have changed our approach to programming 
> significantly beyond text based coding, and into more dynamic mediums of 
> programming in other niches, and even here and there in Xcode - I would 
> recommend considering how the IDE would show a modern version of this 
> concept. I feel too often that Swift design syntax has a lack of awareness 
> between the distinctions of what the IDE should do, as opposed to what the 
> syntax of the language should be, and what should be handled behind the 
> scenes by automated tooling.
> 
> _
> 
> My opinion, in answering the above questions is in preference to a simple 
> easy to read and write syntax, something like the following:
> 
> choices Breakfast {
> Pancake, Waffle, Juice
> }
> 
> If a "default" choice is desired, it is obvious to me that I would select the 
> choice from the IDE, and it would be visually indicated that it was the 
> default.
> 
> When changes occur, whether new choices are added, old ones are removed or 
> changed, or a default is added, changed, or removed - a behind the scenes 
> automated tool analyzes the changes and presents migration options through 
> the IDE.
> 
> _
> 
> Sincerely,
> Jason
> 
> 
> 
> ___
> 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-dev] Make offset index available for String

2018-01-02 Thread Karl Wagner via swift-evolution
And really, this is more an issue for swift-evolution, since what you’re 
talking about (self-incrementing indexes) would be a new language feature.

- Karl

> On 3. Jan 2018, at 01:19, Karl Wagner  wrote:
> 
> Swift used to do this, but we switched it around so indexes couldn’t 
> self-increment.
> 
> One of the problems was that strings are value-types. So you would get an 
> index, then append stuff to the string, but when you tried to advance the 
> index again it would blow up. The index retained the backing, which means the 
> “append” caused a copy, and the index was suddenly pointing to a different 
> String backing.
> 
> Basically, self-incrementing indexes require that the Collection has 
> reference semantics. Otherwise there simply is no concept of an independent 
> “owning” Collection which your Index can hold a reference to.
> 
> Anyway, that doesn’t mean you’re wrong. Collection-slicing syntax is still 
> way too ugly. We need to keep it safe, and communicative, but it should also 
> be obvious and not tiring.
> 
> Currently, you have to write:
> 
> [.index(., offsetBy: )]
> 
> And an example...
> 
> results[results.index(results.startIndex, offsetBy: 3)]
> 
> Which is safe, and communicative, and obvious, but also really, really 
> tiring. There are ways we can make it less tiring without sacrificing the 
> good parts:
> 
> 1) Add a version of index(_: offsetBy:) which takes a KeyPath Self.Index> as its first argument. That’s a minor convenience you can add 
> today in your own projects. It removes one repetition of , in 
> many common cases.
> 
> extension Collection {
>   func index(_ i: KeyPath, offsetBy n: IndexDistance) -> Index {
> return index(self[keyPath: i], offsetBy: n)
>   }
>   func index(_ i: KeyPath, offsetBy n: IndexDistance, limitedBy: 
> Index) -> Index? {
> return index(self[keyPath: i], offsetBy: n, limitedBy: limitedBy)
>   }
> }
> 
> results[results.index(\.startIndex, offsetBy: 3)]
> 
> Seriously, man, KeyPaths are just the business. I love them.
> 
> 2) Bind  to something like an anonymous closure argument within 
> the subscript. Or just allow “.” syntax, as for static members. That removes 
> another .
> 
> results[.index(\.startIndex, offsetBy: 3)]
> 
> or
> 
> results[$.index(\.startIndex, offsetBy: 3)]
> 
> If anybody’s interested, I was playing around with an “IndexExpression” type 
> for this kind of thing. The language lets you get pretty far, but it doesn’t 
> work and I can’t figure out why. It looks like a simple-enough generic 
> struct, but it fails with a cyclic metadata dependency.
> 
> https://gist.github.com/karwa/04cc43431951f24ae9334ba8a25e6a31 
> 
> 
> - Karl
> 
>> On 19. Dec 2017, at 08:38, Cao, Jiannan via swift-dev > > wrote:
>> 
>> I implemented the second approach: SuperIndex
>> 
>> https://github.com/frogcjn/SuperStringIndex/ 
>> 
>> 
>> SuperString is a special version of String. Its SuperIndex keeps a reference 
>> to the string, let the index calculate the offset.
>> 
>> 
>> struct SuperIndex : Comparable, Strideable, CustomStringConvertible {
>> 
>> var owner: Substring
>> var wrapped: String.Index
>>
>>  ...
>> 
>> // Offset
>> var offset: Int {
>> return owner.distance(from: owner.startIndex, to: wrapped)
>> }
>> 
>> // Strideable
>> func advanced(by n: SuperIndex.Stride) -> SuperIndex {
>> return SuperIndex(owner.index(wrapped, offsetBy: n), owner)
>> }
>> 
>> static  func +(lhs: SuperIndex, rhs: SuperIndex.Stride) -> SuperIndex {
>> return lhs.advanced(by: rhs)
>> }
>> }
>> 
>> let a: SuperString = "01234"
>> let o = a.startIndex
>> let o1 = o + 4
>> print(a[o]) // 0
>> print(a[...]) // 01234
>> print(a[..<(o+2)]) // 01
>> print(a[...(o+2)]) // 012
>> print(a[(o+2)...]) // 234
>> print(a[o+2..> print(a[o1-2...o1-1]) // 23
>> 
>> if let number = a.index(of: "1") {
>> print(number) // 1
>> print(a[number...]) // 1234
>> }
>> 
>> if let number = a.index(where: { $0 > "1" }) {
>> print(number) // 2
>> }
>> 
>> let b = a[(o+1)...]
>> let z = b.startIndex
>> let z1 = z + 4
>> print(b[z]) // 1
>> print(b[...]) // 1234
>> print(b[..<(z+2)]) // 12
>> print(b[...(z+2)]) // 123
>> print(b[(z+2)...]) // 34
>> print(b[z+2...z+3]) // 34
>> print(b[z1-2...z1-2]) // 3
>> 
>> 
>>> 在 2017年12月18日,下午4:53,Cao, Jiannan >> > 写道:
>>> 
>>> Or we can copy the design of std::vector::iterator in C++.The index could 
>>> keep a reference to the collection.
>>> When the index being offset by + operator, it could call the owner to 
>>> offset the index, since it keeps a reference to the collection owner.
>>> 
>>> let startIndex = s.startIndex
>>> s[startIndex+1]
>>> 
>>> public struct MyIndex : 

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

2018-01-02 Thread Jonathan Hull via swift-evolution
I think there are a couple of different definitions running around, and that is 
confusing things.

In my mind, ‘unexpected:’ catches only cases which were unknown at compile 
time. Adding cases to an enum *should* be a source-breaking change. That is the 
whole point of this.  We should have to update the switch (either by handling 
new case explicitly, or by adding default) before successfully compiling.  What 
‘unexpected:’ protects against are changes to a linked binary (e.g. iOS) that 
are now vending cases we didn’t know about when we were compiled.

I’ll say it again… framing this idea as one of exhaustiveness is really 
confusing.  Enums should just always be exhaustive in swift.  There may be 
cases where we need to use ‘unexpected:’ to handle unexpected/future cases 
exhaustively.  If we annotate an enum as @frozen, then we won’t need to do that 
to be exhaustive because we know it won’t change out from under us.  Always 
exhaustive. Much less confusing…

Thanks,
Jon



> On Jan 2, 2018, at 1:41 PM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> On Tue, Jan 2, 2018 at 3:27 PM, Kevin Nattinger  > wrote:
> [...]
> 
>>> in what other circumstances do we insist that the compiler inform the end 
>>> user about future additions to the API at compile time?
>> 
>> This isn’t a request for the compiler to inform the user about future 
>> additions to an API.  It is a request to validate the compiler’s knowledge 
>> of the current state of an API with the current state of the source code. 
>> 
>> Well, it's of course impossible to inform the user about future additions, 
>> so that's poorly phrased on my part. It's about the compiler informing the 
>> end user about *new* additions, part of the *current* state of the API, that 
>> have cropped up since the user last revised the code when the API was in a 
>> *previous* state (or, indistinguishably, members of which a user is unaware 
>> regardless of the temporal sequence of when such members were added). In 
>> what other circumstances do we insist that the compiler perform this service?
> 
> Enums. That's literally how they work today. You are arguing in favor of 
> actively removing compiler-aided correctness.
> 
> There's also protocol requirements
> 
> No, that's now how enums work today, and it's not how protocol requirements 
> work today. Enums today are all semantically exhaustive; if a case is added 
> in a later version of a library, it's semantically a *different* enum type 
> that happens to share the same name. Not considering all the cases of an 
> exhaustive enum is an _error_, not a _warning_, because there is no basis on 
> which to proceed. This will not change with the proposal. Likewise, adding a 
> protocol requirement without a default implementation is source-breaking. The 
> result is a compiler _error_.
> 
> The question is, what non-source breaking API additions today cause the 
> compiler to inform the end user of such additions? The answer is: none 
> whatsoever. Not new methods or properties on a type, not even new protocol 
> requirements that have a default implementation.
> 
> 
> and, arguably, deprecated methods with a proper message ("use foo instead").
> 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


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

2018-01-02 Thread Jonathan Hull via swift-evolution
I think this is a good summary.  

I agree that we need to handle unexpected cases from changes to a binary 
somehow.  The main issue is that, when forcing developers to use ‘default’ to 
do it, it also brings along unwanted semantics that prevent warnings in the 
very common use case of a 3rd party library being updated.  The proposal is 
close to what we want, but unacceptable in it’s current form IMHO.

I see two possible solutions to this:

1) A new ‘unexpected:’ construct in switches, which handle cases not known at 
compile time.  This is my favorite option because I think it gives us the most 
freedom to evolve the language in the future.  For example, if we end up adding 
subclassable enums in Swift 12 or something, we will already have a mechanism 
in place to deal with the issues that arise.

2) We version the annotation, and then require any additions to map themselves 
back an existing case for code which doesn’t know about the new case.


I also feel like framing the issue as being about exhaustiveness of enums is 
confusing. It really doesn’t have to be about exhaustiveness at all. I would 
much prefer an annotation like @frozen which can be used for structs as well. 
With @exhaustive you have to start talking about module boundaries, because all 
enums are already exhaustive within the module boundary.  You may find people 
adding @exhaustive for the wrong reasons (i.e. they want their local enum to be 
exhaustive).  Framing the issue as something where we promise not to change the 
API is a much easier mental model to explain to people.

Thanks,
Jon

> On Jan 1, 2018, at 9:48 PM, Chris Lattner via swift-evolution 
>  wrote:
> 
>> On Dec 31, 2017, at 12:14 PM, Matthew Johnson via swift-evolution 
>> > wrote:
>> 
>> I agree that we need a solution to the problem described.  I also agree that 
>> non-exhaustive is most in keeping with the overall design of Swift at module 
>> boundaries.  However, I believe this proposal should be modified before 
>> being accepted
> 
> Thanks for writing this up - you’ve explained a common concern in an 
> interesting way:
> 
>> This is likely to be a relatively rare need mostly encountered by 3rd party 
>> libraries but it will happen.  When it does happen it would be really 
>> unfortunate to be forced to use a `default` clause rather than something 
>> like a `future` clause which will produce an error when compiled against an 
>> SDK where the enum includes cases that are not covered.  I can imagine cases 
>> where this catch-all case would need to do something other than abort the 
>> program so I do not like the `switch!` suggestion that has been discussed.  
>> The programmer should still be responsible for determining the behavior of 
>> unknown cases.
> ..
>> While library authors have a legitimate need to reserve the right to 
>> introduce new cases for some enums this need can be met without taking away 
>> a useful tool for generating static compiler errors when code does not align 
>> with intent (in this case, the intent being to cover all known cases).  
>> Switch statements working with these kinds of enums should be required to 
>> cover unknown cases but should be able to do so while still being statically 
>> checked with regards to known cases.  
> 
> I think that this could be the crux of some major confusion, the root of 
> which is the difference between source packages and binary packages that are 
> updated outside your control (e.g. the OS, or a dynamic library that is 
> updated independently of your app like a 3rd party plugin).  Consider:
> 
> 1) When dealing with independently updated binary packages, your code *has* 
> to implement some behavior for unexpected cases if the enum is 
> non-exhaustive.  It isn’t acceptable to not handle that case, and it isn’t 
> acceptable to abort because then your app will start crashing when a new OS 
> comes out. You have to build some sort of fallback into your app.
> 
> 2) When dealing with a source package that contributes to your app (e.g. 
> through SwiftPM), *YOU* control when you update that package, and therefore 
> it is entirely reasonable to exhaustively handle enums even if that package 
> owner didn’t “intend” for them to be exhaustive.  When *you* chose to update 
> the package, you get the “unhandled case” error, and you have maximal 
> “knowability” about the package’s behavior.
> 
> 
> It seems that your concern stems from the fact that the feature as proposed 
> is aligned around module boundaries, and therefore overly punishes source 
> packages like #2.  I hope you agree that in case #1, that the feature as 
> proposed is the right and only thing we can do: you really do have to handle 
> unknown future cases somehow.
> 
> If I’m getting this right, then maybe there is a variant of the proposal that 
> ties the error/warning behavior to whether or not a module is a source module 
> vs a 

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

2018-01-02 Thread Xiaodi Wu via swift-evolution
On Tue, Jan 2, 2018 at 3:27 PM, Kevin Nattinger  wrote:

> [...]
>
> in what other circumstances do we insist that the compiler inform the end
>> user about future additions to the API at compile time?
>>
>>
>> This isn’t a request for the compiler to inform the user about future
>> additions to an API.  It is a request to validate the compiler’s knowledge
>> of the *current* state of an API with the *current* state of the source
>> code.
>>
>
> Well, it's of course impossible to inform the user about future additions,
> so that's poorly phrased on my part. It's about the compiler informing the
> end user about *new* additions, part of the *current* state of the API,
> that have cropped up since the user last revised the code when the API was
> in a *previous* state (or, indistinguishably, members of which a user is
> unaware regardless of the temporal sequence of when such members were
> added). In what other circumstances do we insist that the compiler perform
> this service?
>
>
> Enums. That's literally how they work today. You are arguing in favor of
> actively removing compiler-aided correctness.
>
> There's also protocol requirements
>

No, that's now how enums work today, and it's not how protocol requirements
work today. Enums today are all semantically exhaustive; if a case is added
in a later version of a library, it's semantically a *different* enum type
that happens to share the same name. Not considering all the cases of an
exhaustive enum is an _error_, not a _warning_, because there is no basis
on which to proceed. This will not change with the proposal. Likewise,
adding a protocol requirement without a default implementation is
source-breaking. The result is a compiler _error_.

The question is, what non-source breaking API additions today cause the
compiler to inform the end user of such additions? The answer is: none
whatsoever. Not new methods or properties on a type, not even new protocol
requirements that have a default implementation.


and, arguably, deprecated methods with a proper message ("use foo instead").
>
___
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-02 Thread Kevin Nattinger via swift-evolution
[...]

>> in what other circumstances do we insist that the compiler inform the end 
>> user about future additions to the API at compile time?
> 
> This isn’t a request for the compiler to inform the user about future 
> additions to an API.  It is a request to validate the compiler’s knowledge of 
> the current state of an API with the current state of the source code. 
> 
> Well, it's of course impossible to inform the user about future additions, so 
> that's poorly phrased on my part. It's about the compiler informing the end 
> user about *new* additions, part of the *current* state of the API, that have 
> cropped up since the user last revised the code when the API was in a 
> *previous* state (or, indistinguishably, members of which a user is unaware 
> regardless of the temporal sequence of when such members were added). In what 
> other circumstances do we insist that the compiler perform this service?

Enums. That's literally how they work today. You are arguing in favor of 
actively removing compiler-aided correctness.

There's also protocol requirements and, arguably, deprecated methods with a 
proper message ("use foo instead").

___
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-02 Thread Karl Wagner via swift-evolution


> On 2. Jan 2018, at 16:38, Matthew Johnson via swift-evolution 
>  wrote:
> 
> 
> 
> Sent from my iPad
> 
> On Jan 1, 2018, at 11:47 PM, Chris Lattner  > wrote:
> 
>>> On Dec 31, 2017, at 12:14 PM, Matthew Johnson via swift-evolution 
>>> > wrote:
>>> 
>>> I agree that we need a solution to the problem described.  I also agree 
>>> that non-exhaustive is most in keeping with the overall design of Swift at 
>>> module boundaries.  However, I believe this proposal should be modified 
>>> before being accepted
>> 
>> Thanks for writing this up - you’ve explained a common concern in an 
>> interesting way:
>> 
>>> This is likely to be a relatively rare need mostly encountered by 3rd party 
>>> libraries but it will happen.  When it does happen it would be really 
>>> unfortunate to be forced to use a `default` clause rather than something 
>>> like a `future` clause which will produce an error when compiled against an 
>>> SDK where the enum includes cases that are not covered.  I can imagine 
>>> cases where this catch-all case would need to do something other than abort 
>>> the program so I do not like the `switch!` suggestion that has been 
>>> discussed.  The programmer should still be responsible for determining the 
>>> behavior of unknown cases.
>> ..
>>> While library authors have a legitimate need to reserve the right to 
>>> introduce new cases for some enums this need can be met without taking away 
>>> a useful tool for generating static compiler errors when code does not 
>>> align with intent (in this case, the intent being to cover all known 
>>> cases).  Switch statements working with these kinds of enums should be 
>>> required to cover unknown cases but should be able to do so while still 
>>> being statically checked with regards to known cases.  
>> 
>> I think that this could be the crux of some major confusion, the root of 
>> which is the difference between source packages and binary packages that are 
>> updated outside your control (e.g. the OS, or a dynamic library that is 
>> updated independently of your app like a 3rd party plugin).  Consider:
>> 
>> 1) When dealing with independently updated binary packages, your code *has* 
>> to implement some behavior for unexpected cases if the enum is 
>> non-exhaustive.  It isn’t acceptable to not handle that case, and it isn’t 
>> acceptable to abort because then your app will start crashing when a new OS 
>> comes out. You have to build some sort of fallback into your app.
>> 
>> 2) When dealing with a source package that contributes to your app (e.g. 
>> through SwiftPM), *YOU* control when you update that package, and therefore 
>> it is entirely reasonable to exhaustively handle enums even if that package 
>> owner didn’t “intend” for them to be exhaustive.  When *you* chose to update 
>> the package, you get the “unhandled case” error, and you have maximal 
>> “knowability” about the package’s behavior.
>> 
>> 
>> It seems that your concern stems from the fact that the feature as proposed 
>> is aligned around module boundaries, and therefore overly punishes source 
>> packages like #2.  I hope you agree that in case #1, that the feature as 
>> proposed is the right and only thing we can do: you really do have to handle 
>> unknown future cases somehow.
>> 
>> If I’m getting this right, then maybe there is a variant of the proposal 
>> that ties the error/warning behavior to whether or not a module is a source 
>> module vs a binary module.  The problem with that right now is that we have 
>> no infrastructure in the language to know this…
> 
> Hi Chris, thanks for your reply.
> 
> The concern you describe isn’t exactly what I was describing but it is 
> related.  John McCall recently posted a sketch of a solution to the concern 
> you describe which looked great to me.  I don’t have time to look up the link 
> this morning but I think it was in this review thread.
> 
> The actual concern I am describing is where a 3rd party library (or app) 
> wants to switch over a non-exhaustive enum provided by a module that is a 
> binary (not source) dependency.  The author of the 3rd party library may have 
> a legitimate reason to switch over an enum despite the author of the binary 
> module reserving the right to add additional cases.  
> 
> When this circumstance arises they will do it using the tools provided by the 
> language.  Regardless of the final language solution they obviously need to 
> cover unknown cases - their library could be shipping on a device which 
> receives an update to the binary dependency that contains a new case.  I 
> agree with you that a language-defined crash is not appropriate.  The author 
> of the switch must take responsibility for the behavior of unknown cases.  
> 
> I am arguing that these “pseudo-exhaustive” switch statements will exist in 
> the wild.  The 

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

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

>
>
> Sent from my iPad
>
> On Jan 2, 2018, at 12:48 PM, Xiaodi Wu  wrote:
>
> On Tue, Jan 2, 2018 at 9:38 AM, Matthew Johnson via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>>
>>
>> Sent from my iPad
>>
>> On Jan 1, 2018, at 11:47 PM, Chris Lattner  wrote:
>>
>> On Dec 31, 2017, at 12:14 PM, Matthew Johnson via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>> I agree that we need a solution to the problem described.  I also agree
>> that non-exhaustive is most in keeping with the overall design of Swift at
>> module boundaries.  However, I believe this proposal should be modified
>> before being accepted
>>
>>
>> Thanks for writing this up - you’ve explained a common concern in an
>> interesting way:
>>
>> This is likely to be a relatively rare need mostly encountered by 3rd
>> party libraries but it will happen.  When it does happen it would be really
>> unfortunate to be forced to use a `default` clause rather than something
>> like a `future` clause which will produce an error when compiled against an
>> SDK where the enum includes cases that are not covered.  I can imagine
>> cases where this catch-all case would need to do something *other than *abort
>> the program so I do not like the `switch!` suggestion that has been
>> discussed.  The programmer should still be responsible for determining the
>> behavior of unknown cases.
>>
>> ..
>>
>> While library authors have a legitimate need to reserve the right to
>> introduce new cases for some enums this need can be met without taking away
>> a useful tool for generating static compiler errors when code does not
>> align with intent (in this case, the intent being to cover all known
>> cases).  Switch statements working with these kinds of enums should be
>> required to cover unknown cases but should be able to do so while still
>> being statically checked with regards to known cases.
>>
>>
>> I think that this could be the crux of some major confusion, the root of
>> which is the difference between source packages and binary packages that
>> are updated outside your control (e.g. the OS, or a dynamic library that is
>> updated independently of your app like a 3rd party plugin).  Consider:
>>
>> 1) When dealing with independently updated binary packages, your code
>> *has* to implement some behavior for unexpected cases if the enum is
>> non-exhaustive.  It isn’t acceptable to not handle that case, and it isn’t
>> acceptable to abort because then your app will start crashing when a new OS
>> comes out. You have to build some sort of fallback into your app.
>>
>> 2) When dealing with a source package that contributes to your app (e.g.
>> through SwiftPM), *YOU* control when you update that package, and therefore
>> it is entirely reasonable to exhaustively handle enums even if that package
>> owner didn’t “intend” for them to be exhaustive.  When *you* chose to
>> update the package, you get the “unhandled case” error, and you have
>> maximal “knowability” about the package’s behavior.
>>
>>
>> It seems that your concern stems from the fact that the feature as
>> proposed is aligned around module boundaries, and therefore overly punishes
>> source packages like #2.  I hope you agree that in case #1, that the
>> feature as proposed is the right and only thing we can do: you really do
>> have to handle unknown future cases somehow.
>>
>> If I’m getting this right, then maybe there is a variant of the proposal
>> that ties the error/warning behavior to whether or not a module is a source
>> module vs a binary module.  The problem with that right now is that we have
>> no infrastructure in the language to know this…
>>
>>
>> Hi Chris, thanks for your reply.
>>
>> The concern you describe isn’t exactly what I was describing but it is
>> related.  John McCall recently posted a sketch of a solution to the concern
>> you describe which looked great to me.  I don’t have time to look up the
>> link this morning but I think it was in this review thread.
>>
>> The actual concern I am describing is where a 3rd party library (or app)
>> wants to switch over a non-exhaustive enum provided by a module that is a
>> binary (not source) dependency.  The author of the 3rd party library may
>> have a legitimate reason to switch over an enum despite the author of the
>> binary module reserving the right to add additional cases.
>>
>> When this circumstance arises they will do it using the tools provided by
>> the language.  Regardless of the final language solution they obviously
>> need to cover unknown cases - their library could be shipping on a device
>> which receives an update to the binary dependency that contains a new
>> case.  I agree with you that a language-defined crash is not appropriate.
>> The author of the switch must take responsibility for the behavior of
>> unknown cases.
>>
>> I am arguing that these 

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

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


Sent from my iPad

> On Jan 2, 2018, at 12:48 PM, Xiaodi Wu  wrote:
> 
>> On Tue, Jan 2, 2018 at 9:38 AM, Matthew Johnson via swift-evolution 
>>  wrote:
>> 
>> 
>> Sent from my iPad
>> 
>> On Jan 1, 2018, at 11:47 PM, Chris Lattner  wrote:
>> 
 On Dec 31, 2017, at 12:14 PM, Matthew Johnson via swift-evolution 
  wrote:
 
 I agree that we need a solution to the problem described.  I also agree 
 that non-exhaustive is most in keeping with the overall design of Swift at 
 module boundaries.  However, I believe this proposal should be modified 
 before being accepted
>>> 
>>> Thanks for writing this up - you’ve explained a common concern in an 
>>> interesting way:
>>> 
 This is likely to be a relatively rare need mostly encountered by 3rd 
 party libraries but it will happen.  When it does happen it would be 
 really unfortunate to be forced to use a `default` clause rather than 
 something like a `future` clause which will produce an error when compiled 
 against an SDK where the enum includes cases that are not covered.  I can 
 imagine cases where this catch-all case would need to do something other 
 than abort the program so I do not like the `switch!` suggestion that has 
 been discussed.  The programmer should still be responsible for 
 determining the behavior of unknown cases.
>>> ..
 While library authors have a legitimate need to reserve the right to 
 introduce new cases for some enums this need can be met without taking 
 away a useful tool for generating static compiler errors when code does 
 not align with intent (in this case, the intent being to cover all known 
 cases).  Switch statements working with these kinds of enums should be 
 required to cover unknown cases but should be able to do so while still 
 being statically checked with regards to known cases.  
>>> 
>>> I think that this could be the crux of some major confusion, the root of 
>>> which is the difference between source packages and binary packages that 
>>> are updated outside your control (e.g. the OS, or a dynamic library that is 
>>> updated independently of your app like a 3rd party plugin).  Consider:
>>> 
>>> 1) When dealing with independently updated binary packages, your code *has* 
>>> to implement some behavior for unexpected cases if the enum is 
>>> non-exhaustive.  It isn’t acceptable to not handle that case, and it isn’t 
>>> acceptable to abort because then your app will start crashing when a new OS 
>>> comes out. You have to build some sort of fallback into your app.
>>> 
>>> 2) When dealing with a source package that contributes to your app (e.g. 
>>> through SwiftPM), *YOU* control when you update that package, and therefore 
>>> it is entirely reasonable to exhaustively handle enums even if that package 
>>> owner didn’t “intend” for them to be exhaustive.  When *you* chose to 
>>> update the package, you get the “unhandled case” error, and you have 
>>> maximal “knowability” about the package’s behavior.
>>> 
>>> 
>>> It seems that your concern stems from the fact that the feature as proposed 
>>> is aligned around module boundaries, and therefore overly punishes source 
>>> packages like #2.  I hope you agree that in case #1, that the feature as 
>>> proposed is the right and only thing we can do: you really do have to 
>>> handle unknown future cases somehow.
>>> 
>>> If I’m getting this right, then maybe there is a variant of the proposal 
>>> that ties the error/warning behavior to whether or not a module is a source 
>>> module vs a binary module.  The problem with that right now is that we have 
>>> no infrastructure in the language to know this…
>> 
>> Hi Chris, thanks for your reply.
>> 
>> The concern you describe isn’t exactly what I was describing but it is 
>> related.  John McCall recently posted a sketch of a solution to the concern 
>> you describe which looked great to me.  I don’t have time to look up the 
>> link this morning but I think it was in this review thread.
>> 
>> The actual concern I am describing is where a 3rd party library (or app) 
>> wants to switch over a non-exhaustive enum provided by a module that is a 
>> binary (not source) dependency.  The author of the 3rd party library may 
>> have a legitimate reason to switch over an enum despite the author of the 
>> binary module reserving the right to add additional cases.  
>> 
>> When this circumstance arises they will do it using the tools provided by 
>> the language.  Regardless of the final language solution they obviously need 
>> to cover unknown cases - their library could be shipping on a device which 
>> receives an update to the binary dependency that contains a new case.  I 
>> agree with you that a language-defined crash is not appropriate.  The author 
>> of the switch must take responsibility for the behavior of 

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

2018-01-02 Thread Xiaodi Wu via swift-evolution
On Tue, Jan 2, 2018 at 1:27 PM, Goffredo Marocchi  wrote:

> Hello all,
>
> On 2 Jan 2018, at 18:36, Xiaodi Wu via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> On Tue, Jan 2, 2018 at 12:11 PM, Jason Merchant via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> I think this whole thing has been unnecessarily convoluted. As a result,
>> the majority of the replies are rabbit holes.
>>
>> In my opinion, the true root of the concept in question is as follows:
>>
>> *A list of something is desired:*
>> 1 - Pancake
>> 2 - Waffle
>> 3 - Juice
>>
>> *Developer wishes to be able to:*
>> *A)* Add new things to the list of choices in the future as they come up
>> with new ideas
>> *B)* Sometimes select one of the choices to be chosen as the normal
>> choice if no choice is made by the user
>>
>> A and B are *separate desires*. In some circumstances a developer may
>> want to add a new choice and make it the normal choice when there was no
>> normal choice was clarified before.
>>
>
> I don't think this is an accurate summary of the problem being tackled
> here. Rather, we are how to enable the vendor of a nonexhaustive enum to
> add new cases without breaking binaries compiled against previous versions.
> There is little here to do with what a "default" should be. Indeed, it is
> an explicit design decision of Swift not to support types having an
> implicit default value.
>
>
> There is no way a library developer of libraries bundled in the app can
> break the app by adding new cases. They may cause compiler issues when the
> app author tries to update the library, but it will not break existing apps.
>
> The concern for updating enums is mostly an Apple / OS related concern for
> libraries/dynamic frameworks the app does not ship with, but links to at
> runtime and we should have an exception for that. We should not use the
> same solution for both and lose exhaustiveness checks when we do not need
> to. It would be wrong.
>

Right, this proposal is about enabling ABI stability and is about libraries
that don't ship with the app.

However, I disagree strongly with your point above. There should not be
dialects of Swift depending on how you link a framework. The point made
above is salient that there are, semantically, certain enums that are
exhaustive (for example, Optional, which can only have two cases), and
others that are nonexhaustive (for example, a list of foods, which will
never be complete).

Those dynamic frameworks should be the one that have to opt-in (even better
> if it is done automatically for them) in non-exhaustive extra resilient
> behaviour, not libraries you ship in the app.
>
> The app developer should be informed and have to address the new cases or
> the removal of old cases.
>
>
>
>> 
>>
>> *Part 2:*
>>
>> After this simple desire is clear, there should be two discussions:
>> *A)* In a text only coding language, what would we like the syntax to
>> look like? (Without regard to past-bias. What should it really be, forget
>> what mistaken design choices were made in Swift in the past)
>> *B)* How do we approach making this happen behind the scenes?
>>
>> *Bonus:* Given that some of us have changed our approach to programming
>> significantly beyond text based coding, and into more dynamic mediums of
>> programming in other niches, and even here and there in Xcode - I would
>> recommend considering how the IDE would show a modern version of this
>> concept. I feel too often that Swift design syntax has a *lack of
>> awareness between the distinctions of what the IDE should do, as opposed to
>> what the syntax of the language should be*, and what should be handled
>> behind the scenes by automated tooling.
>>
>> _
>>
>> *My opinion*, in answering the above questions is in preference to a
>> simple easy to read and write syntax, something like the following:
>>
>> choices Breakfast {
>> Pancake, *Waffle*, Juice
>> }
>>
>> If a "default" choice is desired, it is obvious to me that I would select
>> the choice from the IDE, and it would be visually indicated that it was the
>> default.
>>
>> When changes occur, whether new choices are added, old ones are removed
>> or changed, or a default is added, changed, or removed - a behind the
>> scenes automated tool analyzes the changes and presents migration options
>> through the IDE.
>>
>> _
>>
>> Sincerely,
>> Jason
>>
>>
>>>
>>
>> ___
>> 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] [Review] SE 0192 - Non-Exhaustive Enums

2018-01-02 Thread Goffredo Marocchi via swift-evolution
Hello all,

> On 2 Jan 2018, at 18:36, Xiaodi Wu via swift-evolution 
>  wrote:
> 
>> On Tue, Jan 2, 2018 at 12:11 PM, Jason Merchant via swift-evolution 
>>  wrote:
>> I think this whole thing has been unnecessarily convoluted. As a result, the 
>> majority of the replies are rabbit holes.
>> 
>> In my opinion, the true root of the concept in question is as follows:
>> 
>> A list of something is desired:
>> 1 - Pancake
>> 2 - Waffle
>> 3 - Juice
>> 
>> Developer wishes to be able to:
>> A) Add new things to the list of choices in the future as they come up with 
>> new ideas
>> B) Sometimes select one of the choices to be chosen as the normal choice if 
>> no choice is made by the user
>> 
>> A and B are separate desires. In some circumstances a developer may want to 
>> add a new choice and make it the normal choice when there was no normal 
>> choice was clarified before.
> 
> I don't think this is an accurate summary of the problem being tackled here. 
> Rather, we are how to enable the vendor of a nonexhaustive enum to add new 
> cases without breaking binaries compiled against previous versions. There is 
> little here to do with what a "default" should be. Indeed, it is an explicit 
> design decision of Swift not to support types having an implicit default 
> value.

There is no way a library developer of libraries bundled in the app can break 
the app by adding new cases. They may cause compiler issues when the app author 
tries to update the library, but it will not break existing apps.

The concern for updating enums is mostly an Apple / OS related concern for 
libraries/dynamic frameworks the app does not ship with, but links to at 
runtime and we should have an exception for that. We should not use the same 
solution for both and lose exhaustiveness checks when we do not need to. It 
would be wrong.

Those dynamic frameworks should be the one that have to opt-in (even better if 
it is done automatically for them) in non-exhaustive extra resilient behaviour, 
not libraries you ship in the app. 

The app developer should be informed and have to address the new cases or the 
removal of old cases.

>  
>> 
>> 
>> Part 2:
>> 
>> After this simple desire is clear, there should be two discussions:
>> A) In a text only coding language, what would we like the syntax to look 
>> like? (Without regard to past-bias. What should it really be, forget what 
>> mistaken design choices were made in Swift in the past)
>> B) How do we approach making this happen behind the scenes?
>> 
>> Bonus: Given that some of us have changed our approach to programming 
>> significantly beyond text based coding, and into more dynamic mediums of 
>> programming in other niches, and even here and there in Xcode - I would 
>> recommend considering how the IDE would show a modern version of this 
>> concept. I feel too often that Swift design syntax has a lack of awareness 
>> between the distinctions of what the IDE should do, as opposed to what the 
>> syntax of the language should be, and what should be handled behind the 
>> scenes by automated tooling.
>> 
>> _
>> 
>> My opinion, in answering the above questions is in preference to a simple 
>> easy to read and write syntax, something like the following:
>> 
>> choices Breakfast {
>> Pancake, Waffle, Juice
>> }
>> 
>> If a "default" choice is desired, it is obvious to me that I would select 
>> the choice from the IDE, and it would be visually indicated that it was the 
>> default.
>> 
>> When changes occur, whether new choices are added, old ones are removed or 
>> changed, or a default is added, changed, or removed - a behind the scenes 
>> automated tool analyzes the changes and presents migration options through 
>> the IDE.
>> 
>> _
>> 
>> Sincerely,
>> Jason
>> 
>>> 
>> 
>> 
>> ___
>> 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-0193 - Cross-module inlining and specialization

2018-01-02 Thread Xiaodi Wu via swift-evolution
On Fri, Dec 22, 2017 at 11:12 PM, Slava Pestov  wrote:

>
>
> On Dec 22, 2017, at 7:09 PM, Xiaodi Wu  wrote:
>
> On Fri, Dec 22, 2017 at 6:12 PM, Chris Lattner 
> wrote:
>
>>
>> On Dec 22, 2017, at 1:03 PM, Xiaodi Wu  wrote:
>>
>> In short, respectfully request that you at least add this approach to the
>>> "alternatives considered” section.
>>>
>>>
>>> So, does anyone have any strong objections to Chris’s proposal?
>>>
>>> From an implementation standpoint, reworking the parser to parse
>>> @available(inlinable) and @available(fixedContents) or whatever would be
>>> straightforward. I would still like to punt the version range part of this
>>> to a future proposal, though.
>>>
>>>
>> I wish I had more time to compose a fully thought-out reply, but that's
>> not going to happen in a little while because of outside constraints, so
>> I'll spill a few thoughts here:
>>
>>
>> No rush, no worries, enjoy the holiday!
>>
>> I'm not a great fan of the @available(inlinable) notation.
>>
>> For one, I have a hard time reasoning how Swift would behave when
>> inlinability is tied to OS version. In this example, if the *app* (as
>> opposed to the library) is compiled (as opposed to run) on iOS 16+, then
>> the *library method* would potentially be emitted into the app, but if
>> compiled on iOS 15 it wouldn't? Huh?
>>
>>
>> No: availability information kicks in based on what you are *deploying*
>> to, not what you’re compiling on.
>>
>> I expect that this stuff will be extremely rarely used in practice, but
>> here’s an example:
>>
>> iOS15 declares this public:
>>
>> public void foo() {
>>bar()
>> }
>>
>> iOS16 wants to promote foo to inlinable, but knows that the inlined body
>> doesn’t work with iOS15, because iOS15 needs the call to bar to happen (for
>> whatever reason)
>>
>> @available(inlinable: iOS16)
>> public void foo() {
>>
>> // nothing needed on iOS16 or later.
>>
>> }
>>
>
> Deployment platform makes more sense, but I still can't envision a real
> use case. What sorts of `bar()` would hypothetically be necessary for iOS
> 15 but not 16? Why would a third-party library need to increase its
> inlining availability for an app based on deployment platform?
>
>
> A better example would be if bar() was itself only available in iOS 16:
>
> @available(iOS 15)
> @available(inlinable: iOS 16)
> public func foo() {
>   bar()
> }
>
> @available(iOS 16)
> public func bar() { … }
>
> Suppose your app calls foo() and deploys to iOS 15. Then you cannot inline
> foo(), because bar() does not exist on iOS 15. (Presumably, foo() had a
> different implementation on iOS 15). But if you’re deploying to iOS 16, all
> is well, and you can inline foo(), which results in your app directly
> calling bar().
>
> I'm quite sure that the reason you inverted your "abiPublic" example is
> because of the same issue. Intuitively, you would want to mark something as
> "available" in version N and then maybe some special kind of "available" in
> version N+1 (which @available(inlinable) would be). But
> @available(linkerSymbol), as you spell it, suffers from a similar problem
> to that of @available(unavailable): it's _not_ a special kind of API
> availability, but rather indicates that something is less-than-available.
> That is, you would use it to indicate that something is available as ABI
> but not as API. In that sense, it extends the "mess" we have with
> @available(unavailable).
>
>
> I don’t think it’s quite the same thing as @available(unavailable). An
> @available(abiPublic) symbol would still be declared to have internal
> visibility, so in this case the @available attribute makes it strictly more
> visible than it would be without. We’re not going to spell it as
> ‘@available(abiPublic) public’, which indeed would be confusing because the
> symbol is not actually public at the source level.
>

In Chris's example, it's an annotation of a public API that was once
internal in a previous version:

  @available(apiPublic: iOS 14)
  @available(iOS 15)
  @available(inlinable: iOS 16)
  public func foo() { ... }

This is a sensible use, but it shows how we get to exactly the "indeed
confusing" situation you write about above: here, @available(apiPublic)
elevates the API above internal but below public *even when it annotates a
public API*.
___
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-02 Thread Xiaodi Wu via swift-evolution
On Tue, Jan 2, 2018 at 9:38 AM, Matthew Johnson via swift-evolution <
swift-evolution@swift.org> wrote:

>
>
> Sent from my iPad
>
> On Jan 1, 2018, at 11:47 PM, Chris Lattner  wrote:
>
> On Dec 31, 2017, at 12:14 PM, Matthew Johnson via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> I agree that we need a solution to the problem described.  I also agree
> that non-exhaustive is most in keeping with the overall design of Swift at
> module boundaries.  However, I believe this proposal should be modified
> before being accepted
>
>
> Thanks for writing this up - you’ve explained a common concern in an
> interesting way:
>
> This is likely to be a relatively rare need mostly encountered by 3rd
> party libraries but it will happen.  When it does happen it would be really
> unfortunate to be forced to use a `default` clause rather than something
> like a `future` clause which will produce an error when compiled against an
> SDK where the enum includes cases that are not covered.  I can imagine
> cases where this catch-all case would need to do something *other than *abort
> the program so I do not like the `switch!` suggestion that has been
> discussed.  The programmer should still be responsible for determining the
> behavior of unknown cases.
>
> ..
>
> While library authors have a legitimate need to reserve the right to
> introduce new cases for some enums this need can be met without taking away
> a useful tool for generating static compiler errors when code does not
> align with intent (in this case, the intent being to cover all known
> cases).  Switch statements working with these kinds of enums should be
> required to cover unknown cases but should be able to do so while still
> being statically checked with regards to known cases.
>
>
> I think that this could be the crux of some major confusion, the root of
> which is the difference between source packages and binary packages that
> are updated outside your control (e.g. the OS, or a dynamic library that is
> updated independently of your app like a 3rd party plugin).  Consider:
>
> 1) When dealing with independently updated binary packages, your code
> *has* to implement some behavior for unexpected cases if the enum is
> non-exhaustive.  It isn’t acceptable to not handle that case, and it isn’t
> acceptable to abort because then your app will start crashing when a new OS
> comes out. You have to build some sort of fallback into your app.
>
> 2) When dealing with a source package that contributes to your app (e.g.
> through SwiftPM), *YOU* control when you update that package, and therefore
> it is entirely reasonable to exhaustively handle enums even if that package
> owner didn’t “intend” for them to be exhaustive.  When *you* chose to
> update the package, you get the “unhandled case” error, and you have
> maximal “knowability” about the package’s behavior.
>
>
> It seems that your concern stems from the fact that the feature as
> proposed is aligned around module boundaries, and therefore overly punishes
> source packages like #2.  I hope you agree that in case #1, that the
> feature as proposed is the right and only thing we can do: you really do
> have to handle unknown future cases somehow.
>
> If I’m getting this right, then maybe there is a variant of the proposal
> that ties the error/warning behavior to whether or not a module is a source
> module vs a binary module.  The problem with that right now is that we have
> no infrastructure in the language to know this…
>
>
> Hi Chris, thanks for your reply.
>
> The concern you describe isn’t exactly what I was describing but it is
> related.  John McCall recently posted a sketch of a solution to the concern
> you describe which looked great to me.  I don’t have time to look up the
> link this morning but I think it was in this review thread.
>
> The actual concern I am describing is where a 3rd party library (or app)
> wants to switch over a non-exhaustive enum provided by a module that is a
> binary (not source) dependency.  The author of the 3rd party library may
> have a legitimate reason to switch over an enum despite the author of the
> binary module reserving the right to add additional cases.
>
> When this circumstance arises they will do it using the tools provided by
> the language.  Regardless of the final language solution they obviously
> need to cover unknown cases - their library could be shipping on a device
> which receives an update to the binary dependency that contains a new
> case.  I agree with you that a language-defined crash is not appropriate.
> The author of the switch must take responsibility for the behavior of
> unknown cases.
>
> I am arguing that these “pseudo-exhaustive” switch statements *will*
> exist in the wild.  The crucial point of contention is whether or not the
> language provides assistance to the author of the 3rd party library in
> updating their library when the enum provided by the binary dependency
> changes.  Is 

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

2018-01-02 Thread Xiaodi Wu via swift-evolution
On Tue, Jan 2, 2018 at 12:11 PM, Jason Merchant via swift-evolution <
swift-evolution@swift.org> wrote:

> I think this whole thing has been unnecessarily convoluted. As a result,
> the majority of the replies are rabbit holes.
>
> In my opinion, the true root of the concept in question is as follows:
>
> *A list of something is desired:*
> 1 - Pancake
> 2 - Waffle
> 3 - Juice
>
> *Developer wishes to be able to:*
> *A)* Add new things to the list of choices in the future as they come up
> with new ideas
> *B)* Sometimes select one of the choices to be chosen as the normal
> choice if no choice is made by the user
>
> A and B are *separate desires*. In some circumstances a developer may
> want to add a new choice and make it the normal choice when there was no
> normal choice was clarified before.
>

I don't think this is an accurate summary of the problem being tackled
here. Rather, we are how to enable the vendor of a nonexhaustive enum to
add new cases without breaking binaries compiled against previous versions.
There is little here to do with what a "default" should be. Indeed, it is
an explicit design decision of Swift not to support types having an
implicit default value.


> 
>
> *Part 2:*
>
> After this simple desire is clear, there should be two discussions:
> *A)* In a text only coding language, what would we like the syntax to
> look like? (Without regard to past-bias. What should it really be, forget
> what mistaken design choices were made in Swift in the past)
> *B)* How do we approach making this happen behind the scenes?
>
> *Bonus:* Given that some of us have changed our approach to programming
> significantly beyond text based coding, and into more dynamic mediums of
> programming in other niches, and even here and there in Xcode - I would
> recommend considering how the IDE would show a modern version of this
> concept. I feel too often that Swift design syntax has a *lack of
> awareness between the distinctions of what the IDE should do, as opposed to
> what the syntax of the language should be*, and what should be handled
> behind the scenes by automated tooling.
>
> _
>
> *My opinion*, in answering the above questions is in preference to a
> simple easy to read and write syntax, something like the following:
>
> choices Breakfast {
> Pancake, *Waffle*, Juice
> }
>
> If a "default" choice is desired, it is obvious to me that I would select
> the choice from the IDE, and it would be visually indicated that it was the
> default.
>
> When changes occur, whether new choices are added, old ones are removed or
> changed, or a default is added, changed, or removed - a behind the scenes
> automated tool analyzes the changes and presents migration options through
> the IDE.
>
> _
>
> Sincerely,
> Jason
>
>
>>
>
> ___
> 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] [Proposal] Random Unification

2018-01-02 Thread Xiaodi Wu via swift-evolution
On Tue, Jan 2, 2018 at 10:19 AM, Dave DeLong via swift-evolution <
swift-evolution@swift.org> wrote:

> Just skimmed through the updated proposal and am weighing in with my naïve
> opinions:
>
>
>- I’m still highly skeptical of a static “T.random” API. I’ve yet to
>see a convincing example where it’d be useful to pick a value from the
>range of all possible values. The only truly useful one I’ve seen is “pick
>a random bool”, which could easily be done via “[true, false].random()"
>
>- I much prefer the GameplayKit API[0], which breaks the idea of
>randomness up in to 2 separate concepts:
>   - A “Source” → Where the random numbers come from
>   - A “Distribution” → Initialized with a source, it makes sure the
>   produced numbers exhibit a specific distribution over multiple 
> samplings.
>   Ie, a uniform distribution vs a Gaussian distribution, or something 
> like “I
>   want to pick a card from a deck but bias choices towards Spades or 
> Aces”.
>   I’m also reminded of the anecdote of how iTunes had to modify their
>   “playlist shuffle” algorithm to be less random[1], because the true
>   randomness would do weird things that made it seem not random. Spotify 
> had
>   the same problem and solution[2].
>   - Breaking things up like this would also make it easier to test
>   randomness (by using a replay-able source) but that still follow the
>   parameters of your app (that it has a bell-curve distribution of
>   probabilities, for example)
>
>   - I’d still really really really like to see how this could be done
>as two separate things:
>   - A minimal implementation in the Standard Library (like, defining
>   the base Source and Distribution protocols, with a single default
>   implementation of each)
>   - A proposal for a more complete “non-standard library” where the
>   larger array of functionality would be contained. For example, IMO I 
> don’t
>   think the shuffling stuff needs to be in the standard library. This is 
> also
>   where all the cryptographically secure stuff (that your typical app
>   developer does not need) would live.
>
>   - The “random” element of a collection/range should be “func
>random() → Element?”, not “var random: Element?”. Property values shouldn't
>change between accesses. Ditto the static “Randomizable.random” property.
>
>- What do you think about actively discouraging people from using the
>modulo operator to create a range? It could be done by having the RNGs
>return a “RandomValue” type, then defining a mod operator that takes a
>RandomValue and a T (?), and then giving it a deprecation warning +
>fixit. Not sure if that’d be worth the type overhead, but I’m very much in
>favor of encouraging people towards better practices.
>
>- I’m +1 on crashing if we can’t produce a random number.
>
>- What do you think about the philosophical difference of
>Type.random(using:) vs Type.init(randomSource:)?
>
>
> Dave
>
> [0]: https://developer.apple.com/documentation/gameplaykit/gkrandom
> [1]: https://www.youtube.com/watch?v=lg188Ebas9E=youtu.be=719
> [2]: https://labs.spotify.com/2014/02/28/how-to-shuffle-songs/
>
>

I think these are some excellent points. Earlier, I think, others also
emphasized this idea of exploring what a really minimal implementation in
the standard library would look like, and I've been thinking about this
overnight.

There is much that is commendable about Alejandro's proposal, but I agree
that there is more than needs to be in the standard library. Here's what I
think the shape of a minimal API would look like, which would
simultaneously enable others to implement their desired functionality as an
end user:

- We need very performant, but otherwise barebones, access to system
randomness so that it can be a building block for everything else. Because
this is so special in that it cannot be seeded or initialized, unlike other
RNGs, we don't need this to be a type, and it doesn't need to conform to a
`RandomNumberGenerator` protocol. It can be as straightforward as one or
both of:

-- A global `func random() -> UInt32`, which is essentially `arc4random` on
macOS/iOS and reads from an appropriate secure source on Linux and other
platforms. One pro of having such a method is that it's a drop-in
replacement for `arc4random()` that's _very_ convenient as a primitive to
build up other random operations; one con is that it encourages modulo
bias, although fortunately mostly only with UInt32.
-- An extension method on `UnsafeMutableRawBufferPointer` named `func
copyRandomBytes()`. This would look a lot like Apple's `SecCopyRandomBytes`
and BSD's `arc4random_buf`.

- Having established the primitive, then we can ask what is the minimum
_useful_ functionality for an end user. I think the answer is a very
judicious subset of the currently proposed functionality:

-- An extension method or 

Re: [swift-evolution] [Proposal] Random Unification

2018-01-02 Thread Félix Cloutier via swift-evolution
I'm not sure how much background you have into this thread, but the idea of 
sources and distributions was rejected months ago as almost always too 
cumbersome given that people overwhelmingly want uniform random numbers.

I agree that random() is better as a method. I also think that the default 
Random implementation should be in a class, not a struct. If a generator has 
value semantics, I would expect that two copies would return an identical 
sequence of numbers.

I think that it'll be hard to make a RandomValue that nicely converts to T. 
The best way to discourage modulo is probably to make T.random/T(randomSource:) 
as cumbersome as possible, and Range.random as nice as possible.

> Le 2 janv. 2018 à 11:19, Dave DeLong via swift-evolution 
>  a écrit :
> 
> Just skimmed through the updated proposal and am weighing in with my naïve 
> opinions:
> 
> I’m still highly skeptical of a static “T.random” API. I’ve yet to see a 
> convincing example where it’d be useful to pick a value from the range of all 
> possible values. The only truly useful one I’ve seen is “pick a random bool”, 
> which could easily be done via “[true, false].random()"
> 
> I much prefer the GameplayKit API[0], which breaks the idea of randomness up 
> in to 2 separate concepts:
> A “Source” → Where the random numbers come from
> A “Distribution” → Initialized with a source, it makes sure the produced 
> numbers exhibit a specific distribution over multiple samplings. Ie, a 
> uniform distribution vs a Gaussian distribution, or something like “I want to 
> pick a card from a deck but bias choices towards Spades or Aces”. I’m also 
> reminded of the anecdote of how iTunes had to modify their “playlist shuffle” 
> algorithm to be less random[1], because the true randomness would do weird 
> things that made it seem not random. Spotify had the same problem and 
> solution[2].
> Breaking things up like this would also make it easier to test randomness (by 
> using a replay-able source) but that still follow the parameters of your app 
> (that it has a bell-curve distribution of probabilities, for example)
> 
> I’d still really really really like to see how this could be done as two 
> separate things:
> A minimal implementation in the Standard Library (like, defining the base 
> Source and Distribution protocols, with a single default implementation of 
> each)
> A proposal for a more complete “non-standard library” where the larger array 
> of functionality would be contained. For example, IMO I don’t think the 
> shuffling stuff needs to be in the standard library. This is also where all 
> the cryptographically secure stuff (that your typical app developer does not 
> need) would live.
> 
> The “random” element of a collection/range should be “func random() → 
> Element?”, not “var random: Element?”. Property values shouldn't change 
> between accesses. Ditto the static “Randomizable.random” property.
> 
> What do you think about actively discouraging people from using the modulo 
> operator to create a range? It could be done by having the RNGs return a 
> “RandomValue” type, then defining a mod operator that takes a 
> RandomValue and a T (?), and then giving it a deprecation warning + fixit. 
> Not sure if that’d be worth the type overhead, but I’m very much in favor of 
> encouraging people towards better practices.
> 
> I’m +1 on crashing if we can’t produce a random number. 
> 
> What do you think about the philosophical difference of Type.random(using:) 
> vs Type.init(randomSource:)?
> 
> Dave
> 
> [0]: https://developer.apple.com/documentation/gameplaykit/gkrandom 
> 
> [1]: https://www.youtube.com/watch?v=lg188Ebas9E=youtu.be=719 
> 
> [2]: https://labs.spotify.com/2014/02/28/how-to-shuffle-songs/ 
> 
> 
> 
> 
>> On Jan 2, 2018, at 1:35 AM, Alejandro Alonso via swift-evolution 
>> > wrote:
>> 
>> Hello swift evolution once again, I’ve been hard at work considering every 
>> email and revising the proposal. I’ve made lots of changes and additions to 
>> the proposal to discuss some problems we’ve had (T.random), and walks 
>> through detailed design. You can see the proposal here: 
>> https://github.com/apple/swift-evolution/pull/760 
>>  .
>> 
>> A big issue that lots of people pointed out was `T.random %` and to remove 
>> it completely from the API. To give a gist of why I continue to support 
>> T.random:
>> 
>> 1. Modulo bias misuse is only a problem to types that conform to 
>> `BinaryInteger`. Why remove this functionality if only a portion of the 
>> types have the ability of misuse. `Double.random % 10` is a good example of 
>> where modulo isn’t implemented here as it produces the error, “'%' is 

Re: [swift-evolution] [swift-users] Happy new year Swift community.

2018-01-02 Thread Daniel Montecillo via swift-evolution
Happy New Year from Canada !

On Jan 1, 2018, at 14:02, Kelvin Ma via swift-users 
> wrote:

Happy new year from klossyland!

On Mon, Jan 1, 2018 at 11:23 AM, Georgios Moschovitis via swift-users 
> wrote:
Happy new year! Greetings from Cyprus :)

George.

On 1 Jan 2018, at 1:42 AM, Adrian Zubarev via swift-users 
> wrote:

Well some of you guys have to wait a little longer, but I can already wish 
everyone a happy new year from Germany. 

--
Adrian Zubarev
Sent with Airmail
___
swift-users mailing list
swift-us...@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


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


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


Re: [swift-evolution] [arc optimization] Why doesn't enum destructuring use guaranteed references?

2018-01-02 Thread Chris Lattner via swift-evolution


This is a great question, I’m not sure what the answer is: maybe it is a simple 
case missed by the arc optimizer?

-Chris



> On Dec 27, 2017, at 9:19 PM, Félix Cloutier via swift-evolution 
>  wrote:
> 
> Running this on my MBP with 10 as the parameter: 
> https://gist.github.com/zneak/ae33bb970a08632cfb2925e2049f9e7a 
>  
> 
> I get a runtime of about 10 seconds, 45% of which is spent in retain/release 
> calls according to Instruments (!!), and at least half of that from 
> Expr.count. Looking at the IR, Swift generously sprinkles retain/release 
> calls through the outlined copy method:
> 
> `self` is retained at the beginning of `count`
> The values that you get out of destructuring are retained
> Of course, when you get `count` on these, they are retained again
> 
> Of course, Expr.count cannot modify itself or its subexpressions because the 
> functions are not mutating; in fact, no function in that program can mutate 
> an enum case. Why, then, is Swift retaining/releasing `self` and the values 
> obtained from destructured patterns? They can't go away. Shouldn't we be 
> getting guaranteed references instead of owning references?
> 
> That seems to hit pattern-matching-heavy programs with indirect cases pretty 
> hard, and it's pretty frustrating because that seems to be about the nicest 
> way to write this program, and there's no workaround from the developer's 
> perspective. I don't think that this is a fatal flaw of refcounting, but 
> unless I'm missing something, that's sub-par behavior.
> 
> Félix
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


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

2018-01-02 Thread Jason Merchant via swift-evolution
I think this whole thing has been unnecessarily convoluted. As a result,
the majority of the replies are rabbit holes.

In my opinion, the true root of the concept in question is as follows:

*A list of something is desired:*
1 - Pancake
2 - Waffle
3 - Juice

*Developer wishes to be able to:*
*A)* Add new things to the list of choices in the future as they come up
with new ideas
*B)* Sometimes select one of the choices to be chosen as the normal choice
if no choice is made by the user

A and B are *separate desires*. In some circumstances a developer may want
to add a new choice and make it the normal choice when there was no normal
choice was clarified before.



*Part 2:*

After this simple desire is clear, there should be two discussions:
*A)* In a text only coding language, what would we like the syntax to look
like? (Without regard to past-bias. What should it really be, forget what
mistaken design choices were made in Swift in the past)
*B)* How do we approach making this happen behind the scenes?

*Bonus:* Given that some of us have changed our approach to programming
significantly beyond text based coding, and into more dynamic mediums of
programming in other niches, and even here and there in Xcode - I would
recommend considering how the IDE would show a modern version of this
concept. I feel too often that Swift design syntax has a *lack of awareness
between the distinctions of what the IDE should do, as opposed to what the
syntax of the language should be*, and what should be handled behind the
scenes by automated tooling.

_

*My opinion*, in answering the above questions is in preference to a simple
easy to read and write syntax, something like the following:

choices Breakfast {
Pancake, *Waffle*, Juice
}

If a "default" choice is desired, it is obvious to me that I would select
the choice from the IDE, and it would be visually indicated that it was the
default.

When changes occur, whether new choices are added, old ones are removed or
changed, or a default is added, changed, or removed - a behind the scenes
automated tool analyzes the changes and presents migration options through
the IDE.

_

Sincerely,
Jason


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


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

2018-01-02 Thread Ethan Diamond via swift-evolution

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

This was assigning .x to a, not evaluating a synthesized value

> 
>> a.y // What's the result?
> 
> nil as Optional
> 
>> a.x // Would produce a double optional, which are clumsy to nil check
> 
> They’re a fact of life.  If that’s a problem, we should consider fixing it, 
> but it’s orthogonal to this one.
> 
>> 
>> I'm not a fan of solving this via synthesis in general. We have metatypes 
>> for classes/structs/protocols, which are useful in all sorts of situations. 
>> Cases are essentially "types" of enums. Why not have case metatypes? They're 
>> useful for the same reasons class types are, and there's already precedence 
>> in the language for syntax.
> 
> You mean “precedent?”  OK, but I don’t see how it helps with any of the same 
> problems as synthesized properties for cases do.
> 

I’m not really sure what the problems synthesized properties are trying to 
solve are. Chris brought them up as a possible solution to my pain point, which 
they only solve partially. Checking for a case I don’t know up front (for 
example, comparing the cases of two values) still isn’t covered. 

>> 
>> 
>> 
>> On Thu, Dec 21, 2017 at 7:14 AM Dave Abrahams > > wrote:
>> IIRC what we discussed was synthesizing  members of type Optional 
>> which could then be checked against nil. 
>> 
>> if _ = x.failure { ... }
>> if x.failure != nil { ... }
>> if let r = x.success {...}
>> 
>> IMO synthesizing predicates would be a huge missed opportunity by comparison
>> 
>> Sent from my iPhone
>> 
>> On Dec 20, 2017, at 1:31 PM, Chris Lattner via swift-evolution 
>> > wrote:
>> 
>>> In the past, we’ve discussed synthesizing predicate members onto enums.  
>>> E.g. given:
>>> 
>>> enum E {
>>>   case X
>>>   case Y(Int)
>>> }
>>> 
>>> you’d get something like:
>>> 
>>> extension E {
>>>   func isX() -> Bool { return self == .X }
>>>   func getY() -> Int? { … }
>>> }
>>> 
>>> which would solve the client side of this nicely.
>>> 
>>> -Chris
>>> 
>>> 
>>> 
 On Dec 20, 2017, at 11:24 AM, Ethan Diamond via swift-evolution 
 > wrote:
 
 Sorry all for attaching the original post to the Non-Exhaustive enums 
 thread. I"m moving it down to it's own thread. 
 
 My understanding is I'm not allowed to write up a proposal unless I have 
 the time to implement it. Is that still true? This is a major pain point 
 for me to avoid having to write things like this:
 
 if case .search = presenter.state { return true } else { return false }
 
 Side note: Thanks Kevin, didn't know you could nest enums in switches like 
 that. Super helpful!
 
 --
 I thought I would add another case that isn’t possible with current syntax 
 (so far as I’m aware).  You can’t negate the comparison to do something 
 for all cases except a particular case.  You have to have an empty if 
 block and use the else block, or have an empty case in a switch statement 
 and use the default.
 
 enum Enum {
   case a(param: String)
   case b(param: String)
   case c(param: String)
 }
 
 let enumeration: Enum = .a(param: "Hi")
 
 if !(case .a = enumeration) {
   // Do something
 }
 
 — Charles
 
 > On Dec 20, 2017, at 9:55 AM, Kevin Nattinger via swift-evolution 
 > >>> > > wrote:
 > 
 > I agree this would be useful. At the moment I have to hack around it 
 > with things like `var isFoo: Bool { if case .foo = self …`* with cases I 
 > commonly need, but this is definitely a feature that has come up before 
 > and I support. It is potentially related to getting the values through 
 > an accessor, which has also come up several times.
 > 
 > Sidenote, your `switch` example is actually trivial with existing syntax:
 > 
 > switch enumeration {
 > case .a(.c(let param)): // or just .a(.c) if you don't need the value
 > print(param)
 > default:
 > break
 > }
 > 
 > I use this from time to time switching over, e.g., optional enums.
 > 
 > *: ugliest syntax ever, and it can't even be used as a standalone 
 > expression.
 > 
 > 
 >> On Dec 20, 2017, at 8:44 AM, Ethan Diamond via swift-evolution 
 >> >>> >> 

Re: [swift-evolution] [Proposal] Random Unification

2018-01-02 Thread Dave DeLong via swift-evolution
Just skimmed through the updated proposal and am weighing in with my naïve 
opinions:

I’m still highly skeptical of a static “T.random” API. I’ve yet to see a 
convincing example where it’d be useful to pick a value from the range of all 
possible values. The only truly useful one I’ve seen is “pick a random bool”, 
which could easily be done via “[true, false].random()"

I much prefer the GameplayKit API[0], which breaks the idea of randomness up in 
to 2 separate concepts:
A “Source” → Where the random numbers come from
A “Distribution” → Initialized with a source, it makes sure the produced 
numbers exhibit a specific distribution over multiple samplings. Ie, a uniform 
distribution vs a Gaussian distribution, or something like “I want to pick a 
card from a deck but bias choices towards Spades or Aces”. I’m also reminded of 
the anecdote of how iTunes had to modify their “playlist shuffle” algorithm to 
be less random[1], because the true randomness would do weird things that made 
it seem not random. Spotify had the same problem and solution[2].
Breaking things up like this would also make it easier to test randomness (by 
using a replay-able source) but that still follow the parameters of your app 
(that it has a bell-curve distribution of probabilities, for example)

I’d still really really really like to see how this could be done as two 
separate things:
A minimal implementation in the Standard Library (like, defining the base 
Source and Distribution protocols, with a single default implementation of each)
A proposal for a more complete “non-standard library” where the larger array of 
functionality would be contained. For example, IMO I don’t think the shuffling 
stuff needs to be in the standard library. This is also where all the 
cryptographically secure stuff (that your typical app developer does not need) 
would live.

The “random” element of a collection/range should be “func random() → 
Element?”, not “var random: Element?”. Property values shouldn't change between 
accesses. Ditto the static “Randomizable.random” property.

What do you think about actively discouraging people from using the modulo 
operator to create a range? It could be done by having the RNGs return a 
“RandomValue” type, then defining a mod operator that takes a RandomValue 
and a T (?), and then giving it a deprecation warning + fixit. Not sure if 
that’d be worth the type overhead, but I’m very much in favor of encouraging 
people towards better practices.

I’m +1 on crashing if we can’t produce a random number. 

What do you think about the philosophical difference of Type.random(using:) vs 
Type.init(randomSource:)?

Dave

[0]: https://developer.apple.com/documentation/gameplaykit/gkrandom 

[1]: https://www.youtube.com/watch?v=lg188Ebas9E=youtu.be=719 

[2]: https://labs.spotify.com/2014/02/28/how-to-shuffle-songs/ 




> On Jan 2, 2018, at 1:35 AM, Alejandro Alonso via swift-evolution 
>  wrote:
> 
> Hello swift evolution once again, I’ve been hard at work considering every 
> email and revising the proposal. I’ve made lots of changes and additions to 
> the proposal to discuss some problems we’ve had (T.random), and walks through 
> detailed design. You can see the proposal here: 
> https://github.com/apple/swift-evolution/pull/760 
>  .
> 
> A big issue that lots of people pointed out was `T.random %` and to remove it 
> completely from the API. To give a gist of why I continue to support T.random:
> 
> 1. Modulo bias misuse is only a problem to types that conform to 
> `BinaryInteger`. Why remove this functionality if only a portion of the types 
> have the ability of misuse. `Double.random % 10` is a good example of where 
> modulo isn’t implemented here as it produces the error, “'%' is unavailable: 
> Use truncatingRemainder instead”.
> 
> 2. `Int.random(in: Int.min … Int.max)` doesn’t work. For developers that 
> actually rely on this functionality, the work around that was discussed 
> earlier simply doesn’t work. `Int.min … Int.max`’s count property exceeds 
> that of `Int`’s numerical range. A working work around would be something 
> along the lines of `Int(truncatingIfNeeded: Random.default.next(UInt.self))` 
> which creates a pain point for those developers. As the goal of this proposal 
> to remove pain points regarding random, this change does the opposite.
> 
> I’m interested to hear if anymore discussion around this, or any other issues 
> come up.
> 
> - Alejandro
> 
> On Sep 8, 2017, 11:52 AM -0500, Alejandro Alonso via swift-evolution 
> , wrote:
>> Hello swift evolution, I would like to propose a unified approach to 
>> `random()` in Swift. I have a simple implementation here 
>> 

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

2018-01-02 Thread Drew Crawford via swift-evolution
First, this is an extremely well-written proposal, that explains itself well 
and tries to walk a difficult tightrope.  So, A+ for that.

That said, I think it needs modification before acceptance:

* I agree with Dave DeLong that @exhaustive does not actually "do anything", it 
relies on library authors to do the right thing but library authors cannot be 
trusted.  I am not even sure Optional will continue to have its two cases based 
on the track record of the swift-evolution process :-P
* I agree with Vladimir S that app developers need to be able to use 
compile-time checks that they handle all the "known cases" for an arbitrary 
enum (e.g. exhaustive or non-exhaustive), for example with "future" or some 
other mechanism.  Lack of testability does not actually concern me, but I feel 
it could be addressed by allowing the assignment of Any to a non-exhaustive 
enum, perhaps gated via a warning or an @testable.

I feel that a better solution to the underlying dilemma would be the following:

* As an app developer, I can use switch! or @import! to mean that I am 
vendoring this SDK and the runtime library will definitely be the same library 
I am linking against.  So it does not matter if the library author intends to 
someday add more cases – from my point of of view they are exhaustive, because 
this is the library I am linking, accept no substitutes.  Cases are checked at 
import time, and there is a runtime exception if somebody swaps the binary for 
one with "new" cases, may god have mercy on their soul
* As an app developer, in the absence of one of those opt-in mechanisms an 
imported enum is assumed to be open and I must handle either a default case 
(which is not compile-time checked for exhaustion) or a future case (which is). 
 I prefer "undefined" for "future" as a keyword because it seems to me library 
authors can also remove cases, regardless of what this proposal says.

This solution is a nod to @clattner's "the difference between source packages 
and binary packages that are updated outside your control (e.g. the OS, or a 
dynamic library that is updated independently of your app like a 3rd party 
plugin)."  But he is wrong that the difference is somehow tied together with a 
notion of binary and source: it is a difference between whether the library is 
vendored or nonvendored, that is whether it is shipped with the application or 
the OS.  If it is shipped with your application, you control the updates and so 
all enums can be exhaustive, if it is shipped with the OS it is updated 
independently and who knows what cases will appear at runtime.  But there is no 
law that says I have the sourcecode for all my application's libraries or that 
OS vendors only ship binaries, so I use "vendored" and "non-vendored", and 
"import-time" for "compile-time" to be precise in this distinction.

As a library author, I am not sure that the @exhaustive promise is meaningful.  
Unlike resilience more generally where a library author can provide some 
fallback behavior for client who calls a deprecated method, there is really not 
much that can be done to support older clients who are unaware of my new enum 
case.  I suppose we could introduce compile-time checks to prevent passing that 
enum case to an older client, for example

public enum Foo {
    case old
    @introduced (1.1) case new
}

public final enum Fixed {
    case one
    @introduced (1.1) case two //error: Can't add a new case to a final enum, 
drop @introduced or drop final
}

public func bar() -> Foo {
    return .new //error: Not all clients support case new, use if #available or 
@available
}

This sort of thing might be a justification for supporting a "final" or 
"exhaustive" declaration, but the motivation in this listing is to support 
library authors within their own compilation unit, rather than exposing a 
signal to app developers that may or may not be reliable moving forward.

As shown in this listing, I find "final" more natural and more in the spirit of 
Swift than @exhaustive.

Drew



On December 19, 2017 at 4:58:14 PM, Ted Kremenek (kreme...@apple.com) wrote:

The review of "SE 0192 - Non-Exhaustive Enums" begins now and runs through 
January 3, 2018.

The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md
Reviews are an important part of the Swift evolution process. All review 
feedback should be sent to the swift-evolution mailing list at:

https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review 
manager. 

When replying, please try to keep the proposal link at the top of the message:

Proposal link: 
https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md
...
Reply text
...
Other replies
What goes into a review of a proposal?

The goal of the review process is to improve the proposal under review through 
constructive criticism and, 

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

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


Sent from my iPad

>> On Jan 1, 2018, at 11:47 PM, Chris Lattner  wrote:
>> 
>> On Dec 31, 2017, at 12:14 PM, Matthew Johnson via swift-evolution 
>>  wrote:
>> 
>> I agree that we need a solution to the problem described.  I also agree that 
>> non-exhaustive is most in keeping with the overall design of Swift at module 
>> boundaries.  However, I believe this proposal should be modified before 
>> being accepted
> 
> Thanks for writing this up - you’ve explained a common concern in an 
> interesting way:
> 
>> This is likely to be a relatively rare need mostly encountered by 3rd party 
>> libraries but it will happen.  When it does happen it would be really 
>> unfortunate to be forced to use a `default` clause rather than something 
>> like a `future` clause which will produce an error when compiled against an 
>> SDK where the enum includes cases that are not covered.  I can imagine cases 
>> where this catch-all case would need to do something other than abort the 
>> program so I do not like the `switch!` suggestion that has been discussed.  
>> The programmer should still be responsible for determining the behavior of 
>> unknown cases.
> ..
>> While library authors have a legitimate need to reserve the right to 
>> introduce new cases for some enums this need can be met without taking away 
>> a useful tool for generating static compiler errors when code does not align 
>> with intent (in this case, the intent being to cover all known cases).  
>> Switch statements working with these kinds of enums should be required to 
>> cover unknown cases but should be able to do so while still being statically 
>> checked with regards to known cases.  
> 
> I think that this could be the crux of some major confusion, the root of 
> which is the difference between source packages and binary packages that are 
> updated outside your control (e.g. the OS, or a dynamic library that is 
> updated independently of your app like a 3rd party plugin).  Consider:
> 
> 1) When dealing with independently updated binary packages, your code *has* 
> to implement some behavior for unexpected cases if the enum is 
> non-exhaustive.  It isn’t acceptable to not handle that case, and it isn’t 
> acceptable to abort because then your app will start crashing when a new OS 
> comes out. You have to build some sort of fallback into your app.
> 
> 2) When dealing with a source package that contributes to your app (e.g. 
> through SwiftPM), *YOU* control when you update that package, and therefore 
> it is entirely reasonable to exhaustively handle enums even if that package 
> owner didn’t “intend” for them to be exhaustive.  When *you* chose to update 
> the package, you get the “unhandled case” error, and you have maximal 
> “knowability” about the package’s behavior.
> 
> 
> It seems that your concern stems from the fact that the feature as proposed 
> is aligned around module boundaries, and therefore overly punishes source 
> packages like #2.  I hope you agree that in case #1, that the feature as 
> proposed is the right and only thing we can do: you really do have to handle 
> unknown future cases somehow.
> 
> If I’m getting this right, then maybe there is a variant of the proposal that 
> ties the error/warning behavior to whether or not a module is a source module 
> vs a binary module.  The problem with that right now is that we have no 
> infrastructure in the language to know this…

Hi Chris, thanks for your reply.

The concern you describe isn’t exactly what I was describing but it is related. 
 John McCall recently posted a sketch of a solution to the concern you describe 
which looked great to me.  I don’t have time to look up the link this morning 
but I think it was in this review thread.

The actual concern I am describing is where a 3rd party library (or app) wants 
to switch over a non-exhaustive enum provided by a module that is a binary (not 
source) dependency.  The author of the 3rd party library may have a legitimate 
reason to switch over an enum despite the author of the binary module reserving 
the right to add additional cases.  

When this circumstance arises they will do it using the tools provided by the 
language.  Regardless of the final language solution they obviously need to 
cover unknown cases - their library could be shipping on a device which 
receives an update to the binary dependency that contains a new case.  I agree 
with you that a language-defined crash is not appropriate.  The author of the 
switch must take responsibility for the behavior of unknown cases.  

I am arguing that these “pseudo-exhaustive” switch statements will exist in the 
wild.  The crucial point of contention is whether or not the language provides 
assistance to the author of the 3rd party library in updating their library 
when the enum provided by the binary dependency changes.  Is the author forced 
to use a `default` case which turns of exhaustiveness 

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

2018-01-02 Thread Marc Schlichte via swift-evolution
 We use enums also when modeling JSON responses from our servers. To allow the server side to add new cases without breaking existing clients, we always add an `undefined` case to our enums. Binary frameworks might do the same when exporting enums. When clients compile to a newer version of the framework, new cases will be added and checked by the compiler for exhausiveness. The new version will still contain `undefined` though for the next binary / server-side change.CheersMarc   Von: swift-evolution@swift.orgGesendet: 2. Januar 2018 6:47 vorm.An: matt...@anandabits.comAntworten: clatt...@nondot.orgCc: swift-evolution@swift.orgBetreff: Re: [swift-evolution] [Review] SE 0192 - Non-Exhaustive Enums  On Dec 31, 2017, at 12:14 PM, Matthew Johnson via swift-evolution  wrote:I agree that we need a solution to the problem described.  I also agree that non-exhaustive is most in keeping with the overall design of Swift at module boundaries.  However, I believe this proposal should be modified before being acceptedThanks for writing this up - you’ve explained a common concern in an interesting way:This is likely to be a relatively rare need mostly encountered by 3rd party libraries but it will happen.  When it does happen it would be really unfortunate to be forced to use a `default` clause rather than something like a `future` clause which will produce an error when compiled against an SDK where the enum includes cases that are not covered.  I can imagine cases where this catch-all case would need to do something other than abort the program so I do not like the `switch!` suggestion that has been discussed.  The programmer should still be responsible for determining the behavior of unknown cases...While library authors have a legitimate need to reserve the right to introduce new cases for some enums this need can be met without taking away a useful tool for generating static compiler errors when code does not align with intent (in this case, the intent being to cover all known cases).  Switch statements working with these kinds of enums should be required to cover unknown cases but should be able to do so while still being statically checked with regards to known cases.  I think that this could be the crux of some major confusion, the root of which is the difference between source packages and binary packages that are updated outside your control (e.g. the OS, or a dynamic library that is updated independently of your app like a 3rd party plugin).  Consider:1) When dealing with independently updated binary packages, your code *has* to implement some behavior for unexpected cases if the enum is non-exhaustive.  It isn’t acceptable to not handle that case, and it isn’t acceptable to abort because then your app will start crashing when a new OS comes out. You have to build some sort of fallback into your app.2) When dealing with a source package that contributes to your app (e.g. through SwiftPM), *YOU* control when you update that package, and therefore it is entirely reasonable to exhaustively handle enums even if that package owner didn’t “intend” for them to be exhaustive.  When *you* chose to update the package, you get the “unhandled case” error, and you have maximal “knowability” about the package’s behavior.It seems that your concern stems from the fact that the feature as proposed is aligned around module boundaries, and therefore overly punishes source packages like #2.  I hope you agree that in case #1, that the feature as proposed is the right and only thing we can do: you really do have to handle unknown future cases somehow.If I’m getting this right, then maybe there is a variant of the proposal that ties the error/warning behavior to whether or not a module is a source module vs a binary module.  The problem with that right now is that we have no infrastructure in the language to know this…-Chris___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal] Random Unification

2018-01-02 Thread Xiaodi Wu via swift-evolution
On Tue, Jan 2, 2018 at 2:35 AM, Alejandro Alonso via swift-evolution <
swift-evolution@swift.org> wrote:

> Hello swift evolution once again, I’ve been hard at work considering every
> email and revising the proposal. I’ve made lots of changes and additions to
> the proposal to discuss some problems we’ve had (T.random), and walks
> through detailed design. You can see the proposal here:
> https://github.com/apple/swift-evolution/pull/760 .
>
> A big issue that lots of people pointed out was `T.random %` and to remove
> it completely from the API. To give a gist of why I continue to support
> T.random:
>
> 1. Modulo bias misuse is only a problem to types that conform to
> `BinaryInteger`. Why remove this functionality if only a portion of the
> types have the ability of misuse. `Double.random % 10` is a good example of
> where modulo isn’t implemented here as it produces the error, “'%' is
> unavailable: Use truncatingRemainder instead”.
>
> 2. `Int.random(in: Int.min … Int.max)` doesn’t work. For developers that
> actually rely on this functionality, the work around that was discussed
> earlier simply doesn’t work. `Int.min … Int.max`’s count property exceeds
> that of `Int`’s numerical range. A working work around would be something
> along the lines of `Int(truncatingIfNeeded: Random.default.next(UInt.self))`
> which creates a pain point for those developers. As the goal of this
> proposal to remove pain points regarding random, this change does the
> opposite.
>
> I’m interested to hear if anymore discussion around this, or any other
> issues come up.
>

There is no reason why `(Int.min...Int.max).random` (as I believe the
consensus suggestion was) "doesn't work." Certainly, it doesn't work if you
write only a default implementation on Collection. But `Range where Bound :
FixedWidthInteger & SignedInteger` should have its own implementation of
`random` anyway (for performance reasons, if nothing else) and there is no
impediment to a working implementation.

As to your first point: as evidenced by concrete data given by others
above, the overwhelming majority of uses of `random %` appear to be
erroneous, and of course the great majority of uses of `T.random` will be
on types that conform to `BinaryInteger`. Again, I repeat my concern that
you are naming multiple distinct things "random", which is making it
difficult to carry on this discussion. `BinaryInteger.random` is distinct
in its semantics, and this is precisely the method that is often used and
often misused. There is no reason why other things that you name "random"
shouldn't exist just because `BinaryInteger` shouldn't have a method named
`random`, and it's spurious to say "why remove this functionality if only a
portion of the types have the ability of misuse," when this _functionality_
and its misuse are specific to `BinaryInteger`.


On Sep 8, 2017, 11:52 AM -0500, Alejandro Alonso via swift-evolution <
> swift-evolution@swift.org>, wrote:
>
> Hello swift evolution, I would like to propose a unified approach to
> `random()` in Swift. I have a simple implementation here
> https://gist.github.com/Azoy/5d294148c8b97d20b96ee64f434bb4f5. This
> implementation is a simple wrapper over existing random functions so
> existing code bases will not be affected. Also, this approach introduces a
> new random feature for Linux users that give them access to upper bounds,
> as well as a lower bound for both Glibc and Darwin users. This change would
> be implemented within Foundation.
>
> I believe this simple change could have a very positive impact on new
> developers learning Swift and experienced developers being able to write
> single random declarations.
>
> I’d like to hear about your ideas on this proposal, or any implementation
> changes if need be.
>
> - Alejando
>
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2018-01-02 Thread Nevin Brackett-Rozinsky via swift-evolution
On Tue, Jan 2, 2018 at 12:47 AM, Chris Lattner via swift-evolution <
swift-evolution@swift.org> wrote:
>
>
> 1) When dealing with independently updated binary packages, your code
> *has* to implement some behavior for unexpected cases if the enum is
> non-exhaustive.  It isn’t acceptable to not handle that case, and it isn’t
> acceptable to abort because then your app will start crashing when a new OS
> comes out. You have to build some sort of fallback into your app.
>

Yes, absolutely.



> 2) When dealing with a source package that contributes to your app (e.g.
> through SwiftPM), *YOU* control when you update that package, and therefore
> it is entirely reasonable to exhaustively handle enums even if that package
> owner didn’t “intend” for them to be exhaustive.  When *you* chose to
> update the package, you get the “unhandled case” error, and you have
> maximal “knowability” about the package’s behavior.
>

I agree 100%



> It seems that your concern stems from the fact that the feature as
> proposed is aligned around module boundaries, and therefore overly punishes
> source packages like #2.  I hope you agree that in case #1, that the
> feature as proposed is the right and only thing we can do: you really do
> have to handle unknown future cases somehow.
>

I take slight exception to the word “only” here: the proposal as written
does not offer compile-time feedback to inform client programmers that
external enums on which they “switch” have new cases, because they are
required to include a “default” clause.

Yes, those client programmers need to handle unknown cases, but they *also*
deserve the compiler’s assistance in identifying when such cases have been
added. I don’t know if a “future” keyword is the best approach, but we
ought to include some way to warn (not error) when compiling a switch
statement that the author intends to be exhaustive-over-all-known-cases
while also handling unknown ones.



> If I’m getting this right, then maybe there is a variant of the proposal
> that ties the error/warning behavior to whether or not a module is a source
> module vs a binary module.  The problem with that right now is that we have
> no infrastructure in the language to know this…
>
> -Chris
>

If we can make that work, this proposal will be much more palatable.

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


Re: [swift-evolution] [Proposal] Random Unification

2018-01-02 Thread Alejandro Alonso via swift-evolution
Hello swift evolution once again, I’ve been hard at work considering every 
email and revising the proposal. I’ve made lots of changes and additions to the 
proposal to discuss some problems we’ve had (T.random), and walks through 
detailed design. You can see the proposal here: 
https://github.com/apple/swift-evolution/pull/760 .

A big issue that lots of people pointed out was `T.random %` and to remove it 
completely from the API. To give a gist of why I continue to support T.random:

1. Modulo bias misuse is only a problem to types that conform to 
`BinaryInteger`. Why remove this functionality if only a portion of the types 
have the ability of misuse. `Double.random % 10` is a good example of where 
modulo isn’t implemented here as it produces the error, “'%' is unavailable: 
Use truncatingRemainder instead”.

2. `Int.random(in: Int.min … Int.max)` doesn’t work. For developers that 
actually rely on this functionality, the work around that was discussed earlier 
simply doesn’t work. `Int.min … Int.max`’s count property exceeds that of 
`Int`’s numerical range. A working work around would be something along the 
lines of `Int(truncatingIfNeeded: Random.default.next(UInt.self))` which 
creates a pain point for those developers. As the goal of this proposal to 
remove pain points regarding random, this change does the opposite.

I’m interested to hear if anymore discussion around this, or any other issues 
come up.

- Alejandro

On Sep 8, 2017, 11:52 AM -0500, Alejandro Alonso via swift-evolution 
, wrote:
Hello swift evolution, I would like to propose a unified approach to `random()` 
in Swift. I have a simple implementation here 
https://gist.github.com/Azoy/5d294148c8b97d20b96ee64f434bb4f5. This 
implementation is a simple wrapper over existing random functions so existing 
code bases will not be affected. Also, this approach introduces a new random 
feature for Linux users that give them access to upper bounds, as well as a 
lower bound for both Glibc and Darwin users. This change would be implemented 
within Foundation.

I believe this simple change could have a very positive impact on new 
developers learning Swift and experienced developers being able to write single 
random declarations.

I’d like to hear about your ideas on this proposal, or any implementation 
changes if need be.

- Alejando

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