Re: [swift-evolution] Fix "private extension" (was "Public Access Modifier Respected in Type Definition")

2017-10-06 Thread Jose Cheyo Jimenez via swift-evolution

> On Oct 6, 2017, at 9:35 PM, Tony Allevato  wrote:
> 
> 
> 
> On Fri, Oct 6, 2017 at 9:29 PM Jose Cheyo Jimenez  > wrote:
>> On Oct 6, 2017, at 8:58 PM, Tony Allevato > > wrote:
>> 
>> 
>> 
>> On Fri, Oct 6, 2017 at 8:45 PM Jose Cheyo Jimenez > > wrote:
>>> On Oct 6, 2017, at 8:01 PM, Tony Allevato >> > wrote:
>>> 
>>> At the time SE-0025 was accepted, "private extension" would have been 
>>> meaningless if it did not mean "fileprivate" because it predated the 
>>> SE-0169 behavior extending "private" to extensions in the same file. The 
>>> very issue being debated here is whether the oversight that SE-0169 did not 
>>> consider extensions—now that "private extension" *could* have a meaningful 
>>> use separate from "fileprivate extension"—is something that is worth 
>>> correcting.
>>> 
>>> If the documentation is out-of-date and needs to be updated to list 
>>> describe unintuitive special behavior, why not use the opportunity to make 
>>> the behavior intuitive and consistent instead?
>> 
>> Lets say you “fix” the private extension override. Now MyClass2.myFunc2() is 
>> not accessible from outside the type. 
>> Wouldn't MyClass2.myFunc2() now be inconsistent with MyClass.myFunc()? 
>> I don’t think you can make a change to one with out causing other 
>> inconsistencies. I rest my case.  :) 
>> 
>> No, because a class is a concrete "thing" whose access level which—while 
>> providing an upper bound for access levels of its defaulting members—is 
>> otherwise independent of the access level of its members.
>> 
>> Extensions, on the other hand, aren't a concrete thing of their own. The 
>> access level on an extension exists *solely* as a shortcut to specify the 
>> upper bound for its defaulting members that are injected into the main type.
>> 
>> What happens in your example if you replace "private" with "public"? Then 
>> myFunc has internal access but myFunc2 is public. So the "inconsistency" 
>> you're pointing out between access inherited from a type and access 
>> inherited from an extension already exists—they're apples and oranges.
>> 
>> That's why access levels of classes/structs/other types aren't relevant 
>> examples here—extensions treat access levels fundamentally differently.
> 
> Sure. Extensions apply a default upper bound and types can lower the upper 
> bound of the default internal members. The upper bound on the below example 
> is the same for both when dealing with top level private.
> 
> Extensions should resolve their upper bound accessibility where the ‘private’ 
> appears explicitly and this now happens to be the same for both types and 
> extensions regardless of how they are enforced. 
> 
> But *why* do you think that should be? You're stating what the current 
> situation is and you say that it "should" be that way, but why should we 
> accept that status quo instead of making "private extension" more useful for 
> people who use "private" in the sense introduced by SE-0169, when the 
> argument for consistency can honestly be argued either way (the two options I 
> wrote a few messages up)?

Oh :) Because I believe that lowering the scope of “private extension” would 
undermine the spirit of 169.  169 was a compromise after 159 was rejected. 169 
was meant to make fileprivate less common and thus more meaningful when it 
occurs in source. Where 169 was meant to relax the rules, the proposed “fix” 
would force people who now use “private extension” to use “fileprivate 
extension” thus making fileprivate more common. In other words, 169 was about 
relaxing rules and not about tightening down the rules or allowing “true” 
private to be applied as a default ACL extension.

“scoped" `private extension` can’t be archived now in the same way that ‘open 
extension’ is not allowed. The lowest and highest ACL are not able to be 
applied as default  extension modifiers and this makes sense to me. 

There is no solution that will make everyone happy: maintaining the status quo 
makes “fileprivate” too common and therefore not meaningful when it occurs in 
source; removing or diluting scope-level access control (as in SE-0159 
>
 and this proposal)
https://lists.swift.org/pipermail/swift-evolution-announce/2017-April/000357.html
 




> 
>  
>> 
>> private class MyClass {
>> static func myFunc(){ // This would now act differently from private 
>> extensions? 
>> print("acts like fileprivate now")
>> }
>> }
>> 
>> private class MyClass2 {}
>> 
>> 

Re: [swift-evolution] Fix "private extension" (was "Public Access Modifier Respected in Type Definition")

2017-10-06 Thread Tony Allevato via swift-evolution
On Fri, Oct 6, 2017 at 9:29 PM Jose Cheyo Jimenez 
wrote:

> On Oct 6, 2017, at 8:58 PM, Tony Allevato  wrote:
>
>
>
> On Fri, Oct 6, 2017 at 8:45 PM Jose Cheyo Jimenez 
> wrote:
>
>> On Oct 6, 2017, at 8:01 PM, Tony Allevato 
>> wrote:
>>
>>>
>>> At the time SE-0025 was accepted, "private extension" would have been
>> meaningless if it did not mean "fileprivate" because it predated the
>> SE-0169 behavior extending "private" to extensions in the same file. The
>> very issue being debated here is whether the oversight that SE-0169 did not
>> consider extensions—now that "private extension" *could* have a meaningful
>> use separate from "fileprivate extension"—is something that is worth
>> correcting.
>>
>> If the documentation is out-of-date and needs to be updated to list
>> describe unintuitive special behavior, why not use the opportunity to make
>> the behavior intuitive and consistent instead?
>>
>>
>> Lets say you “fix” the private extension override. Now MyClass2.myFunc2()
>> is not accessible from outside the type.
>> Wouldn't MyClass2.myFunc2() now be inconsistent with MyClass.myFunc()?
>> I don’t think you can make a change to one with out causing other
>> inconsistencies. I rest my case.  :)
>>
>
> No, because a class is a concrete "thing" whose access level which—while
> providing an upper bound for access levels of its defaulting members—is
> otherwise independent of the access level of its members.
>
> Extensions, on the other hand, aren't a concrete thing of their own. The
> access level on an extension exists *solely* as a shortcut to specify the
> upper bound for its defaulting members that are injected into the main type.
>
> What happens in your example if you replace "private" with "public"? Then
> myFunc has internal access but myFunc2 is public. So the "inconsistency"
> you're pointing out between access inherited from a type and access
> inherited from an extension already exists—they're apples and oranges.
>
> That's why access levels of classes/structs/other types aren't relevant
> examples here—extensions treat access levels fundamentally differently.
>
> Sure. Extensions apply a default upper bound and types can lower the upper
> bound of the default internal members. The upper bound on the below example
> is the same for both when dealing with top level private.
>
> Extensions should resolve their upper bound accessibility where the
> ‘private’ appears explicitly and this now happens to be the same for both
> types and extensions regardless of how they are enforced.
>

But *why* do you think that should be? You're stating what the current
situation is and you say that it "should" be that way, but why should we
accept that status quo instead of making "private extension" more useful
for people who use "private" in the sense introduced by SE-0169, when the
argument for consistency can honestly be argued either way (the two options
I wrote a few messages up)?



>
>> private class MyClass {
>> static func myFunc(){ // This would now act differently from private
>> extensions?
>> print("acts like fileprivate now")
>> }
>> }
>>
>> private class MyClass2 {}
>>
>> private extension MyClass2{
>>   static func myFunc2(){
>>print("Same as MyClass.myFunc")
>> }
>> }
>>
>>
>> MyClass.myFunc() // acts like fileprivate
>> MyClass2.myFunc2() // The proposed change would hide myFunc2
>>  //Error: 'myFunc2' is inaccessible due to 'private'
>> protection level
>>
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Fix "private extension" (was "Public Access Modifier Respected in Type Definition")

2017-10-06 Thread Jose Cheyo Jimenez via swift-evolution

> On Oct 6, 2017, at 8:58 PM, Tony Allevato  wrote:
> 
> 
> 
> On Fri, Oct 6, 2017 at 8:45 PM Jose Cheyo Jimenez  > wrote:
>> On Oct 6, 2017, at 8:01 PM, Tony Allevato > > wrote:
>> 
>> At the time SE-0025 was accepted, "private extension" would have been 
>> meaningless if it did not mean "fileprivate" because it predated the SE-0169 
>> behavior extending "private" to extensions in the same file. The very issue 
>> being debated here is whether the oversight that SE-0169 did not consider 
>> extensions—now that "private extension" *could* have a meaningful use 
>> separate from "fileprivate extension"—is something that is worth correcting.
>> 
>> If the documentation is out-of-date and needs to be updated to list describe 
>> unintuitive special behavior, why not use the opportunity to make the 
>> behavior intuitive and consistent instead?
> 
> Lets say you “fix” the private extension override. Now MyClass2.myFunc2() is 
> not accessible from outside the type. 
> Wouldn't MyClass2.myFunc2() now be inconsistent with MyClass.myFunc()? 
> I don’t think you can make a change to one with out causing other 
> inconsistencies. I rest my case.  :) 
> 
> No, because a class is a concrete "thing" whose access level which—while 
> providing an upper bound for access levels of its defaulting members—is 
> otherwise independent of the access level of its members.
> 
> Extensions, on the other hand, aren't a concrete thing of their own. The 
> access level on an extension exists *solely* as a shortcut to specify the 
> upper bound for its defaulting members that are injected into the main type.
> 
> What happens in your example if you replace "private" with "public"? Then 
> myFunc has internal access but myFunc2 is public. So the "inconsistency" 
> you're pointing out between access inherited from a type and access inherited 
> from an extension already exists—they're apples and oranges.
> 
> That's why access levels of classes/structs/other types aren't relevant 
> examples here—extensions treat access levels fundamentally differently.
Sure. Extensions apply a default upper bound and types can lower the upper 
bound of the default internal members. The upper bound on the below example is 
the same for both when dealing with top level private.

Extensions should resolve their upper bound accessibility where the ‘private’ 
appears explicitly and this now happens to be the same for both types and 
extensions regardless of how they are enforced. 
> 
> private class MyClass {
> static func myFunc(){ // This would now act differently from private 
> extensions? 
> print("acts like fileprivate now")
> }
> }
> 
> private class MyClass2 {}
> 
> private extension MyClass2{
>   static func myFunc2(){
>print("Same as MyClass.myFunc")
> }
> }
> 
> 
> MyClass.myFunc() // acts like fileprivate
> MyClass2.myFunc2() // The proposed change would hide myFunc2
>  //Error: 'myFunc2' is inaccessible due to 'private' protection 
> level

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


Re: [swift-evolution] Fix "private extension" (was "Public Access Modifier Respected in Type Definition")

2017-10-06 Thread Tony Allevato via swift-evolution
On Fri, Oct 6, 2017 at 8:45 PM Jose Cheyo Jimenez 
wrote:

> On Oct 6, 2017, at 8:01 PM, Tony Allevato  wrote:
>
>>
>> At the time SE-0025 was accepted, "private extension" would have been
> meaningless if it did not mean "fileprivate" because it predated the
> SE-0169 behavior extending "private" to extensions in the same file. The
> very issue being debated here is whether the oversight that SE-0169 did not
> consider extensions—now that "private extension" *could* have a meaningful
> use separate from "fileprivate extension"—is something that is worth
> correcting.
>
> If the documentation is out-of-date and needs to be updated to list
> describe unintuitive special behavior, why not use the opportunity to make
> the behavior intuitive and consistent instead?
>
>
> Lets say you “fix” the private extension override. Now MyClass2.myFunc2()
> is not accessible from outside the type.
> Wouldn't MyClass2.myFunc2() now be inconsistent with MyClass.myFunc()?
> I don’t think you can make a change to one with out causing other
> inconsistencies. I rest my case.  :)
>

No, because a class is a concrete "thing" whose access level which—while
providing an upper bound for access levels of its defaulting members—is
otherwise independent of the access level of its members.

Extensions, on the other hand, aren't a concrete thing of their own. The
access level on an extension exists *solely* as a shortcut to specify the
upper bound for its defaulting members that are injected into the main type.

What happens in your example if you replace "private" with "public"? Then
myFunc has internal access but myFunc2 is public. So the "inconsistency"
you're pointing out between access inherited from a type and access
inherited from an extension already exists—they're apples and oranges.

That's why access levels of classes/structs/other types aren't relevant
examples here—extensions treat access levels fundamentally differently.


>
> private class MyClass {
> static func myFunc(){ // This would now act differently from private
> extensions?
> print("acts like fileprivate now")
> }
> }
>
> private class MyClass2 {}
>
> private extension MyClass2{
>   static func myFunc2(){
>print("Same as MyClass.myFunc")
> }
> }
>
>
> MyClass.myFunc() // acts like fileprivate
> MyClass2.myFunc2() // The proposed change would hide myFunc2
>  //Error: 'myFunc2' is inaccessible due to 'private'
> protection level
>
>
>
>
>
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Fix "private extension" (was "Public Access Modifier Respected in Type Definition")

2017-10-06 Thread Jose Cheyo Jimenez via swift-evolution

> On Oct 6, 2017, at 8:01 PM, Tony Allevato  wrote:
> 
> At the time SE-0025 was accepted, "private extension" would have been 
> meaningless if it did not mean "fileprivate" because it predated the SE-0169 
> behavior extending "private" to extensions in the same file. The very issue 
> being debated here is whether the oversight that SE-0169 did not consider 
> extensions—now that "private extension" *could* have a meaningful use 
> separate from "fileprivate extension"—is something that is worth correcting.
> 
> If the documentation is out-of-date and needs to be updated to list describe 
> unintuitive special behavior, why not use the opportunity to make the 
> behavior intuitive and consistent instead?

Lets say you “fix” the private extension override. Now MyClass2.myFunc2() is 
not accessible from outside the type. 
Wouldn't MyClass2.myFunc2() now be inconsistent with MyClass.myFunc()? 
I don’t think you can make a change to one with out causing other 
inconsistencies. I rest my case.  :) 


private class MyClass {
static func myFunc(){ // This would now act differently from private 
extensions? 
print("acts like fileprivate now")
}
}

private class MyClass2 {}

private extension MyClass2{
  static func myFunc2(){
   print("Same as MyClass.myFunc")
}
}


MyClass.myFunc() // acts like fileprivate
MyClass2.myFunc2() // The proposed change would hide myFunc2
 //Error: 'myFunc2' is inaccessible due to 'private' protection 
level






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


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

2017-10-06 Thread Chris Lattner via swift-evolution

> On Oct 5, 2017, at 10:58 AM, Nate Cook via swift-evolution 
>  wrote:
> 
> The edge case is really the same (empty ranges), it’s about what we do with 
> the edge case. If we include the methods on integer types, usage will look 
> like this:
> 
> let x = Int.random(in: 0..<5) // 3
> let y = Int.random(in: 0..<0) // runtime error
> 
> If we only have the collection methods, usage will look like this:
> 
> let x = (0..<5).random()! // 3
> let y = (0..<0).random()! // runtime error

These aren’t the forms I was suggesting, what I meant was:

extension Int {
  init(randomInRange: Countable{Closed}Range)
}

which gives:
let x = Int(randomInRange: 0..<5)

The point of this is that you’re producing an Int (or whatever type).  
Regardless of whether the initializer is failable or not, this is the preferred 
way of creating a new value with some property: it is an initializer with a 
label.

-Chris


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


Re: [swift-evolution] Fix "private extension" (was "Public Access Modifier Respected in Type Definition")

2017-10-06 Thread Tony Allevato via swift-evolution
On Fri, Oct 6, 2017 at 7:07 PM Jose Cheyo Jimenez 
wrote:

> On Oct 6, 2017, at 11:07 AM, Tony Allevato 
> wrote:
>
> On Fri, Oct 6, 2017 at 10:16 AM Jose Cheyo Jimenez via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> On Oct 6, 2017, at 7:10 AM, Vladimir.S  wrote:
>>
>> On 05.10.2017 20:52, Jose Cheyo Jimenez via swift-evolution wrote:
>>
>> On Oct 5, 2017, at 4:32 AM, David Hart > mailto:da...@hartbit.com >> wrote:
>>
>>
>> On 5 Oct 2017, at 07:34, Jose Cheyo Jimenez via swift-evolution <
>> swift-evolution@swift.org > >> wrote:
>>
>> I appreciate the enthusiasm but this is not a bug. This was a deliberate
>> change in swift 3 to make `private extension` usable. If this was a bug
>> then during swift 3 we should have disallowed `private extension` and only
>> allowed `fileprivate extension` but that is not what happened. `private
>> extension` has worked the same since swift 1. I’ve always used `private
>> extension` when I want to add methods to String or other build in types.
>>
>>
>> It’s not a bug, but its unfortunate the behaviour wasn’t changed at the
>> same time as SE-0169, and it now is very inconsistent. I also don’t have to
>> rehash previous discussions, but if a Core Team member (Chris) is okay with
>> going ahead with this, perhaps we should consider it.
>>
>> This could have not been part of 169 because it would've required to
>> lower the visibility of the private extension modifier.
>> “No migration will be necessary as this proposal merely broadens the
>> visibility of|private|.”
>> There was a corner case mentioned when dealing with functions with the
>> same name and that was understandable.
>> private extension is consistent to the way the private scope rules work.
>> The word private is explicit at the top level because extensions can only
>> be declared at top level. Top level private is always fileprivate. The
>> inconsistency is that we have 1 scope ALC and the rest are not. An explicit
>> declaration should always take precedence when declaring something like an
>> access level override.
>>
>>
>> FWIW, I can't agree with this. 'private extension' is a real point of
>> additional confusion for access levels in Swift.
>> Extension *by itself* has no access level, we only can specify the
>> *default* (and the top most) access level for inner methods.
>> I.e. 'private' access modifier for extension has not the same meaning as
>> 'private' func/type/variable at file scope.
>> (Yes, I also believe we should disallow 'private' keyword at file level
>> and allow it only for extensions, so 'fileprivate' should be used
>> explicitly if one needs this. At least warning should be raised. This is
>> the *root* of the problem we discuss now. But unfortunately I don't expect
>> this could be supported.)
>>
>>
>> Wouldn't that just add a *special* rule to extensions? :)
>>
>> The latter is 'direct' access level for the func/type/variable and here
>> we apply the standard rule for scoped private, so 'private' for file scope
>> --> 'fileprivate'.
>>
>> The former means 'the default(and top most) modifier that will be
>> auto-inserted by compiler for all nested methods in extension'. This
>> relatively simple rule should not be complicated by additional rule as ",
>> but if it is private extension, result access level will be fileprivate,
>> you can't have extensions with private methods”
>>
>>
>> Private as it exist in swift now is the scope access control label. The
>> compiler does not insert the modifier without having to first compute what
>> access control level would be applied to the members of the extension.
>> Doing it the other way would be counterintuitive for an scope access label.
>> In my code base I disallow top level fileprivate because private top level
>> is fileprivate. This is a matter of taste and a linter here would help like
>> a mentioned up thread.
>>
>
> This is the sticking point, which is why there are two possible
> interpretations of "private extension":
>
> Choice 1) Attach-then-evaluate. "ACL extension { ... }" is a syntactic
> shortcut for "extension { ACL ... }". Under that definition, the ACL is
> evaluated as if it were attached to each declaration, so "private
> extension" would expand to "private" in front of each decl.
>
> Choice 2) Evaluate-then-attach. "ACL extension { ... }" is evaluated such
> that "ACL" takes on the meaning based on its scope; since it's equivalent
> to "fileprivate" there, that is what is attached to each declaration inside
> the extension.
>
>
> Yep. This is the issue. Nice summary!
>
>
> The phrasing in the official Swift language guide doesn't specifically
> state it, but I think most readers would interpret the following as #1:
>
>
> "Alternatively, you can mark an extension with an explicit access-level
> modifier (for example, `private extension`) to 

Re: [swift-evolution] Fix "private extension" (was "Public Access Modifier Respected in Type Definition")

2017-10-06 Thread Jose Cheyo Jimenez via swift-evolution

> On Oct 6, 2017, at 11:07 AM, Tony Allevato  wrote:
> 
> On Fri, Oct 6, 2017 at 10:16 AM Jose Cheyo Jimenez via swift-evolution 
> > wrote:
>> On Oct 6, 2017, at 7:10 AM, Vladimir.S > > wrote:
>> 
>> On 05.10.2017 20:52, Jose Cheyo Jimenez via swift-evolution wrote:
 On Oct 5, 2017, at 4:32 AM, David Hart >> wrote:
 
> 
> On 5 Oct 2017, at 07:34, Jose Cheyo Jimenez via swift-evolution 
>  
> >> 
> wrote:
> 
> I appreciate the enthusiasm but this is not a bug. This was a deliberate 
> change in swift 3 to make `private extension` usable. If this was a bug 
> then during swift 3 we should have disallowed `private extension` and 
> only allowed `fileprivate extension` but that is not what happened. 
> `private extension` has worked the same since swift 1. I’ve always used 
> `private extension` when I want to add methods to String or other build 
> in types. 
 
 It’s not a bug, but its unfortunate the behaviour wasn’t changed at the 
 same time as SE-0169, and it now is very inconsistent. I also don’t have 
 to rehash previous discussions, but if a Core Team member (Chris) is okay 
 with going ahead with this, perhaps we should consider it.
>>> This could have not been part of 169 because it would've required to lower 
>>> the visibility of the private extension modifier.
>>> “No migration will be necessary as this proposal merely broadens the 
>>> visibility of|private|.”
>>> There was a corner case mentioned when dealing with functions with the same 
>>> name and that was understandable.
>>> private extension is consistent to the way the private scope rules work. 
>>> The word private is explicit at the top level because extensions can only 
>>> be declared at top level. Top level private is always fileprivate. The 
>>> inconsistency is that we have 1 scope ALC and the rest are not. An explicit 
>>> declaration should always take precedence when declaring something like an 
>>> access level override.
>> 
>> FWIW, I can't agree with this. 'private extension' is a real point of 
>> additional confusion for access levels in Swift.
>> Extension *by itself* has no access level, we only can specify the *default* 
>> (and the top most) access level for inner methods.
>> I.e. 'private' access modifier for extension has not the same meaning as 
>> 'private' func/type/variable at file scope.
>> (Yes, I also believe we should disallow 'private' keyword at file level and 
>> allow it only for extensions, so 'fileprivate' should be used explicitly if 
>> one needs this. At least warning should be raised. This is the *root* of the 
>> problem we discuss now. But unfortunately I don't expect this could be 
>> supported.)
> 
> Wouldn't that just add a special rule to extensions? :)
> 
> 
>> The latter is 'direct' access level for the func/type/variable and here we 
>> apply the standard rule for scoped private, so 'private' for file scope --> 
>> 'fileprivate'.
>> 
> 
>> The former means 'the default(and top most) modifier that will be 
>> auto-inserted by compiler for all nested methods in extension'. This 
>> relatively simple rule should not be complicated by additional rule as ", 
>> but if it is private extension, result access level will be fileprivate, you 
>> can't have extensions with private methods”
> 
> Private as it exist in swift now is the scope access control label. The 
> compiler does not insert the modifier without having to first compute what 
> access control level would be applied to the members of the extension.  Doing 
> it the other way would be counterintuitive for an scope access label. In my 
> code base I disallow top level fileprivate because private top level is 
> fileprivate. This is a matter of taste and a linter here would help like a 
> mentioned up thread.
> 
> This is the sticking point, which is why there are two possible 
> interpretations of "private extension":
> 
> Choice 1) Attach-then-evaluate. "ACL extension { ... }" is a syntactic 
> shortcut for "extension { ACL ... }". Under that definition, the ACL is 
> evaluated as if it were attached to each declaration, so "private extension" 
> would expand to "private" in front of each decl.
> 
> Choice 2) Evaluate-then-attach. "ACL extension { ... }" is evaluated such 
> that "ACL" takes on the meaning based on its scope; since it's equivalent to 
> "fileprivate" there, that is what is attached to each declaration inside the 
> extension.

Yep. This is the issue. Nice summary!

> The phrasing in the official Swift language guide doesn't specifically state 
> it, but I think most readers 

Re: [swift-evolution] Pitch: Restrict Cross-module Struct Initializers

2017-10-06 Thread Jordan Rose via swift-evolution
Oh, sorry, the missing piece of that is 'inlinable': an inlinable memberwise 
initializer in a fixed-layout struct should have no performance overhead in an 
optimized build.

Jordan


> On Oct 6, 2017, at 15:25, Jordan Rose  wrote:
> 
> Good question. Slava and I talked about that and decided that there wasn't 
> much point. '_fixed_layout' still doesn't cover the invariant problem, and 
> memberwise initializers are really common when that's not relevant. We don't 
> think there should ever be a reason to write _fixed_layout in a source 
> package, and we wouldn't want this to become one.
> 
> Jordan
> 
> 
>> On Oct 6, 2017, at 15:23, Xiaodi Wu > > wrote:
>> 
>> Presumably, @_fixed_layout and its future formalized cousin would restore 
>> the current functionality?
>> 
>> 
>> On Fri, Oct 6, 2017 at 16:32 Jordan Rose via swift-evolution 
>> > wrote:
>> While working on the non-exhaustive enums proposal I had it pointed out to 
>> me that structs actually currently leak implementation details across module 
>> boundaries, specifically their full set of stored properties. This only 
>> comes up in one place: when making an initializer for the struct in an 
>> extension in another module. We really want people to be able to change the 
>> stored properties in their structs between releases without it being a 
>> source break—that's half the point of computed properties—and it's also 
>> important for a struct author to be able to enforce invariants across the 
>> struct's properties. So after talking to a few other Apple Swift folks I put 
>> together this proposal:
>> 
>> https://github.com/jrose-apple/swift-evolution/blob/restrict-cross-module-struct-initializers/proposals/-restrict-cross-module-struct-initializers.md
>>  
>> 
>> 
>> This one's way smaller than the enum one, and hopefully fairly 
>> uncontroversial. Feedback welcome!
>> 
>> 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] Pitch: Restrict Cross-module Struct Initializers

2017-10-06 Thread Jordan Rose via swift-evolution
Good question. Slava and I talked about that and decided that there wasn't much 
point. '_fixed_layout' still doesn't cover the invariant problem, and 
memberwise initializers are really common when that's not relevant. We don't 
think there should ever be a reason to write _fixed_layout in a source package, 
and we wouldn't want this to become one.

Jordan


> On Oct 6, 2017, at 15:23, Xiaodi Wu  wrote:
> 
> Presumably, @_fixed_layout and its future formalized cousin would restore the 
> current functionality?
> 
> 
> On Fri, Oct 6, 2017 at 16:32 Jordan Rose via swift-evolution 
> > wrote:
> While working on the non-exhaustive enums proposal I had it pointed out to me 
> that structs actually currently leak implementation details across module 
> boundaries, specifically their full set of stored properties. This only comes 
> up in one place: when making an initializer for the struct in an extension in 
> another module. We really want people to be able to change the stored 
> properties in their structs between releases without it being a source 
> break—that's half the point of computed properties—and it's also important 
> for a struct author to be able to enforce invariants across the struct's 
> properties. So after talking to a few other Apple Swift folks I put together 
> this proposal:
> 
> https://github.com/jrose-apple/swift-evolution/blob/restrict-cross-module-struct-initializers/proposals/-restrict-cross-module-struct-initializers.md
>  
> 
> 
> This one's way smaller than the enum one, and hopefully fairly 
> uncontroversial. Feedback welcome!
> 
> 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] Pitch: Restrict Cross-module Struct Initializers

2017-10-06 Thread Xiaodi Wu via swift-evolution
Presumably, @_fixed_layout and its future formalized cousin would restore
the current functionality?


On Fri, Oct 6, 2017 at 16:32 Jordan Rose via swift-evolution <
swift-evolution@swift.org> wrote:

> While working on the non-exhaustive enums proposal I had it pointed out to
> me that *structs* actually currently leak implementation details across
> module boundaries, specifically their full set of stored properties. This
> only comes up in one place: when making an initializer for the struct in an
> extension in another module. We really want people to be able to change the
> stored properties in their structs between releases without it being a
> source break—that's half the point of computed properties—and it's also
> important for a struct author to be able to enforce invariants across the
> struct's properties. So after talking to a few other Apple Swift folks I
> put together this proposal:
>
>
> https://github.com/jrose-apple/swift-evolution/blob/restrict-cross-module-struct-initializers/proposals/-restrict-cross-module-struct-initializers.md
>
> This one's way smaller than the enum one, and hopefully fairly
> uncontroversial. Feedback welcome!
>
> 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] Pitch: Restrict Cross-module Struct Initializers

2017-10-06 Thread Tony Allevato via swift-evolution
Yes, this feels right. I was a little unsure/unclear about this at first,
but the example with `let` and invariants convinced me, and now I can see
how changing a stored property to a computed property later could cause
problems in your scenario.

So even though *technically* there is some subset of structs (PODs, mainly)
where creating extra-module initializers could feasibly work, I think it
makes complete sense to align with classes here because what we want to say
is that "the only person who knows enough about a type to initialize it is
the module who defines it; anyone else should have to go through them to
get an instance".

Strong +1 from me.

On Fri, Oct 6, 2017 at 2:32 PM Jordan Rose via swift-evolution <
swift-evolution@swift.org> wrote:

> While working on the non-exhaustive enums proposal I had it pointed out to
> me that *structs* actually currently leak implementation details across
> module boundaries, specifically their full set of stored properties. This
> only comes up in one place: when making an initializer for the struct in an
> extension in another module. We really want people to be able to change the
> stored properties in their structs between releases without it being a
> source break—that's half the point of computed properties—and it's also
> important for a struct author to be able to enforce invariants across the
> struct's properties. So after talking to a few other Apple Swift folks I
> put together this proposal:
>
>
> https://github.com/jrose-apple/swift-evolution/blob/restrict-cross-module-struct-initializers/proposals/-restrict-cross-module-struct-initializers.md
>
> This one's way smaller than the enum one, and hopefully fairly
> uncontroversial. Feedback welcome!
>
> 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


[swift-evolution] Pitch: Restrict Cross-module Struct Initializers

2017-10-06 Thread Jordan Rose via swift-evolution
While working on the non-exhaustive enums proposal I had it pointed out to me 
that structs actually currently leak implementation details across module 
boundaries, specifically their full set of stored properties. This only comes 
up in one place: when making an initializer for the struct in an extension in 
another module. We really want people to be able to change the stored 
properties in their structs between releases without it being a source 
break—that's half the point of computed properties—and it's also important for 
a struct author to be able to enforce invariants across the struct's 
properties. So after talking to a few other Apple Swift folks I put together 
this proposal:

https://github.com/jrose-apple/swift-evolution/blob/restrict-cross-module-struct-initializers/proposals/-restrict-cross-module-struct-initializers.md
 


This one's way smaller than the enum one, and hopefully fairly uncontroversial. 
Feedback welcome!

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


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

2017-10-06 Thread Ben Cohen via swift-evolution


> On Oct 4, 2017, at 19:26, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> extension Data {
>   static func random(byteCount: Int) -> Data
> }
> 


Instead of methods on specific concrete types, I’d prefer to have a Sequence or 
Collection-conforming type that you could compose with existing operations like 
init from a Sequence or replaceSubrange:

// Just a rough sketch...
struct RandomNumbers: RandomAccessCollection {
let _range: ClosedRange
let _count: Int

var startIndex: Int { return 0 }
var endIndex: Int { return _count }
subscript(i: Int) -> T { return _range.random() }

init(of: T.Type, count: Int) {
_range = T.min...T.max
_count = count
}
init(count: Int) {
self = RandomNumbers(of: T.self, count: count)
}
// possibly a constructor that takes a specific range
init(in: R, count: Int) where R.Bound == T {
// etc
}
}

for x in RandomNumbers(of: UInt8.self, count: 10) {
print(x)
}

let d = Data(RandomNumbers(count: 10))

var a = Array(0..<10)
a.replaceSubrange(5..., with: RandomNumbers(count: 5))

The tricky thing is that making it a Collection violates the (admittedly 
unwritten) rule that a collection should be multi-pass, in the sense that 
multiple passes produce different numbers. Then again, so can lazy collections 
with impure closures. At least it isn’t variable length (unlike a lazy filter). 
And making it a collection of defined size means it can be used efficiently 
with things like append and replaceSubrange which reserve space in advance


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


Re: [swift-evolution] Fix "private extension" (was "Public Access Modifier Respected in Type Definition")

2017-10-06 Thread Tony Allevato via swift-evolution
On Fri, Oct 6, 2017 at 10:16 AM Jose Cheyo Jimenez via swift-evolution <
swift-evolution@swift.org> wrote:

> On Oct 6, 2017, at 7:10 AM, Vladimir.S  wrote:
>
> On 05.10.2017 20:52, Jose Cheyo Jimenez via swift-evolution wrote:
>
> On Oct 5, 2017, at 4:32 AM, David Hart  mailto:da...@hartbit.com >> wrote:
>
>
> On 5 Oct 2017, at 07:34, Jose Cheyo Jimenez via swift-evolution <
> swift-evolution@swift.org  >> wrote:
>
> I appreciate the enthusiasm but this is not a bug. This was a deliberate
> change in swift 3 to make `private extension` usable. If this was a bug
> then during swift 3 we should have disallowed `private extension` and only
> allowed `fileprivate extension` but that is not what happened. `private
> extension` has worked the same since swift 1. I’ve always used `private
> extension` when I want to add methods to String or other build in types.
>
>
> It’s not a bug, but its unfortunate the behaviour wasn’t changed at the
> same time as SE-0169, and it now is very inconsistent. I also don’t have to
> rehash previous discussions, but if a Core Team member (Chris) is okay with
> going ahead with this, perhaps we should consider it.
>
> This could have not been part of 169 because it would've required to lower
> the visibility of the private extension modifier.
> “No migration will be necessary as this proposal merely broadens the
> visibility of|private|.”
> There was a corner case mentioned when dealing with functions with the
> same name and that was understandable.
> private extension is consistent to the way the private scope rules work.
> The word private is explicit at the top level because extensions can only
> be declared at top level. Top level private is always fileprivate. The
> inconsistency is that we have 1 scope ALC and the rest are not. An explicit
> declaration should always take precedence when declaring something like an
> access level override.
>
>
> FWIW, I can't agree with this. 'private extension' is a real point of
> additional confusion for access levels in Swift.
> Extension *by itself* has no access level, we only can specify the
> *default* (and the top most) access level for inner methods.
> I.e. 'private' access modifier for extension has not the same meaning as
> 'private' func/type/variable at file scope.
> (Yes, I also believe we should disallow 'private' keyword at file level
> and allow it only for extensions, so 'fileprivate' should be used
> explicitly if one needs this. At least warning should be raised. This is
> the *root* of the problem we discuss now. But unfortunately I don't expect
> this could be supported.)
>
>
> Wouldn't that just add a *special* rule to extensions? :)
>
> The latter is 'direct' access level for the func/type/variable and here we
> apply the standard rule for scoped private, so 'private' for file scope -->
> 'fileprivate'.
>
> The former means 'the default(and top most) modifier that will be
> auto-inserted by compiler for all nested methods in extension'. This
> relatively simple rule should not be complicated by additional rule as ",
> but if it is private extension, result access level will be fileprivate,
> you can't have extensions with private methods”
>
>
> Private as it exist in swift now is the scope access control label. The
> compiler does not insert the modifier without having to first compute what
> access control level would be applied to the members of the extension.
> Doing it the other way would be counterintuitive for an scope access label.
> In my code base I disallow top level fileprivate because private top level
> is fileprivate. This is a matter of taste and a linter here would help like
> a mentioned up thread.
>

This is the sticking point, which is why there are two possible
interpretations of "private extension":

Choice 1) Attach-then-evaluate. "ACL extension { ... }" is a syntactic
shortcut for "extension { ACL ... }". Under that definition, the ACL is
evaluated as if it were attached to each declaration, so "private
extension" would expand to "private" in front of each decl.

Choice 2) Evaluate-then-attach. "ACL extension { ... }" is evaluated such
that "ACL" takes on the meaning based on its scope; since it's equivalent
to "fileprivate" there, that is what is attached to each declaration inside
the extension.

The phrasing in the official Swift language guide doesn't specifically
state it, but I think most readers would interpret the following as #1:

"Alternatively, you can mark an extension with an explicit access-level
modifier (for example, `private extension`) to set a new default access
level for all members defined within the extension."

I personally find that choice to be the clearer interpretation of the rule,
because it's based entirely on what words are in the source file and not
about how they interact in special edge cases.

I also think it's hard to rationalize "private 

Re: [swift-evolution] Fix "private extension" (was "Public Access Modifier Respected in Type Definition")

2017-10-06 Thread Xiaodi Wu via swift-evolution
These exceed the confines of the narrow discussion we are trying to have
here about private extensions. We are not going to rehash the ugliness of
fileprivate.
On Fri, Oct 6, 2017 at 12:16 Jose Cheyo Jimenez via swift-evolution <
swift-evolution@swift.org> wrote:

> On Oct 6, 2017, at 7:10 AM, Vladimir.S  wrote:
>
> On 05.10.2017 20:52, Jose Cheyo Jimenez via swift-evolution wrote:
>
> On Oct 5, 2017, at 4:32 AM, David Hart  mailto:da...@hartbit.com >> wrote:
>
>
> On 5 Oct 2017, at 07:34, Jose Cheyo Jimenez via swift-evolution <
> swift-evolution@swift.org  >> wrote:
>
> I appreciate the enthusiasm but this is not a bug. This was a deliberate
> change in swift 3 to make `private extension` usable. If this was a bug
> then during swift 3 we should have disallowed `private extension` and only
> allowed `fileprivate extension` but that is not what happened. `private
> extension` has worked the same since swift 1. I’ve always used `private
> extension` when I want to add methods to String or other build in types.
>
>
> It’s not a bug, but its unfortunate the behaviour wasn’t changed at the
> same time as SE-0169, and it now is very inconsistent. I also don’t have to
> rehash previous discussions, but if a Core Team member (Chris) is okay with
> going ahead with this, perhaps we should consider it.
>
> This could have not been part of 169 because it would've required to lower
> the visibility of the private extension modifier.
> “No migration will be necessary as this proposal merely broadens the
> visibility of|private|.”
> There was a corner case mentioned when dealing with functions with the
> same name and that was understandable.
> private extension is consistent to the way the private scope rules work.
> The word private is explicit at the top level because extensions can only
> be declared at top level. Top level private is always fileprivate. The
> inconsistency is that we have 1 scope ALC and the rest are not. An explicit
> declaration should always take precedence when declaring something like an
> access level override.
>
>
> FWIW, I can't agree with this. 'private extension' is a real point of
> additional confusion for access levels in Swift.
> Extension *by itself* has no access level, we only can specify the
> *default* (and the top most) access level for inner methods.
> I.e. 'private' access modifier for extension has not the same meaning as
> 'private' func/type/variable at file scope.
> (Yes, I also believe we should disallow 'private' keyword at file level
> and allow it only for extensions, so 'fileprivate' should be used
> explicitly if one needs this. At least warning should be raised. This is
> the *root* of the problem we discuss now. But unfortunately I don't expect
> this could be supported.)
>
>
> Wouldn't that just add a *special* rule to extensions? :)
>
> The latter is 'direct' access level for the func/type/variable and here we
> apply the standard rule for scoped private, so 'private' for file scope -->
> 'fileprivate'.
>
> The former means 'the default(and top most) modifier that will be
> auto-inserted by compiler for all nested methods in extension'. This
> relatively simple rule should not be complicated by additional rule as ",
> but if it is private extension, result access level will be fileprivate,
> you can't have extensions with private methods”
>
>
> Private as it exist in swift now is the scope access control label. The
> compiler does not insert the modifier without having to first compute what
> access control level would be applied to the members of the extension.
> Doing it the other way would be counterintuitive for an scope access label.
> In my code base I disallow top level fileprivate because private top level
> is fileprivate. This is a matter of taste and a linter here would help like
> a mentioned up thread.
>
>
> And, as was already said, this inconsistency leads to *relaxed* access
> level, which can lead to bugs. If one expects 'private extension' means
> 'fileprivate extension' - compiler will show(with error) that this
> assumption is wrong just after the first attempt to access methods from
> outside of the extended type.
> But if one expects true 'private' access level - the methods from private
> extension could be called from any other code in the same file(by mistake,
> or because code was written a long time ago, or by another developer) and
> this clearly could produce complex bugs.
>
> Also, isn't it a strange code below:
>
> private extension MyType {
>  func foo() {}
>  private bar() {}
>  fileprivate baz() {} // note that "usually" fileprivate is 'wider' access
> level
> }
>
>
> This is also strange too :)
>
>  fileprivate class MyType {
>   open func foo(){}  // Is this open or fileprivate?
>   public func bar(){}
> }
>
>  open class MyType2 {
> }
>
> open extension MyType2 { // Error: Extensions cannot use 'open' as 

Re: [swift-evolution] Fix "private extension" (was "Public Access Modifier Respected in Type Definition")

2017-10-06 Thread Jose Cheyo Jimenez via swift-evolution

> On Oct 6, 2017, at 7:10 AM, Vladimir.S  wrote:
> 
> On 05.10.2017 20:52, Jose Cheyo Jimenez via swift-evolution wrote:
>>> On Oct 5, 2017, at 4:32 AM, David Hart >> > wrote:
>>> 
 
 On 5 Oct 2017, at 07:34, Jose Cheyo Jimenez via swift-evolution 
 > wrote:
 
 I appreciate the enthusiasm but this is not a bug. This was a deliberate 
 change in swift 3 to make `private extension` usable. If this was a bug 
 then during swift 3 we should have disallowed `private extension` and only 
 allowed `fileprivate extension` but that is not what happened. `private 
 extension` has worked the same since swift 1. I’ve always used `private 
 extension` when I want to add methods to String or other build in types. 
>>> 
>>> It’s not a bug, but its unfortunate the behaviour wasn’t changed at the 
>>> same time as SE-0169, and it now is very inconsistent. I also don’t have to 
>>> rehash previous discussions, but if a Core Team member (Chris) is okay with 
>>> going ahead with this, perhaps we should consider it.
>> This could have not been part of 169 because it would've required to lower 
>> the visibility of the private extension modifier.
>> “No migration will be necessary as this proposal merely broadens the 
>> visibility of|private|.”
>> There was a corner case mentioned when dealing with functions with the same 
>> name and that was understandable.
>> private extension is consistent to the way the private scope rules work. The 
>> word private is explicit at the top level because extensions can only be 
>> declared at top level. Top level private is always fileprivate. The 
>> inconsistency is that we have 1 scope ALC and the rest are not. An explicit 
>> declaration should always take precedence when declaring something like an 
>> access level override.
> 
> FWIW, I can't agree with this. 'private extension' is a real point of 
> additional confusion for access levels in Swift.
> Extension *by itself* has no access level, we only can specify the *default* 
> (and the top most) access level for inner methods.
> I.e. 'private' access modifier for extension has not the same meaning as 
> 'private' func/type/variable at file scope.
> (Yes, I also believe we should disallow 'private' keyword at file level and 
> allow it only for extensions, so 'fileprivate' should be used explicitly if 
> one needs this. At least warning should be raised. This is the *root* of the 
> problem we discuss now. But unfortunately I don't expect this could be 
> supported.)

Wouldn't that just add a special rule to extensions? :)

> The latter is 'direct' access level for the func/type/variable and here we 
> apply the standard rule for scoped private, so 'private' for file scope --> 
> 'fileprivate'.
> 
> The former means 'the default(and top most) modifier that will be 
> auto-inserted by compiler for all nested methods in extension'. This 
> relatively simple rule should not be complicated by additional rule as ", but 
> if it is private extension, result access level will be fileprivate, you 
> can't have extensions with private methods”

Private as it exist in swift now is the scope access control label. The 
compiler does not insert the modifier without having to first compute what 
access control level would be applied to the members of the extension.  Doing 
it the other way would be counterintuitive for an scope access label. In my 
code base I disallow top level fileprivate because private top level is 
fileprivate. This is a matter of taste and a linter here would help like a 
mentioned up thread.

> 
> And, as was already said, this inconsistency leads to *relaxed* access level, 
> which can lead to bugs. If one expects 'private extension' means 'fileprivate 
> extension' - compiler will show(with error) that this assumption is wrong 
> just after the first attempt to access methods from outside of the extended 
> type.
> But if one expects true 'private' access level - the methods from private 
> extension could be called from any other code in the same file(by mistake, or 
> because code was written a long time ago, or by another developer) and this 
> clearly could produce complex bugs.
> 
> Also, isn't it a strange code below:
> 
> private extension MyType {
>  func foo() {}
>  private bar() {}
>  fileprivate baz() {} // note that "usually" fileprivate is 'wider' access 
> level
> }

This is also strange too :)

 fileprivate class MyType {
  open func foo(){}  // Is this open or fileprivate?
  public func bar(){} 
}

 open class MyType2 {
}

open extension MyType2 { // Error: Extensions cannot use 'open' as their 
default access; use 'public'
func baz(){}
}


> 
> but it has *currently* a sense - 'foo' is fileprivate, and 'bar' is 'true' 
> private.
> Yes, currently we have a warning about 'baz': "warning: declaring a 
> fileprivate instance method in a 

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

2017-10-06 Thread Félix Cloutier via swift-evolution
I agree that as an operation, .randomElement() feels closer to .first and .last 
(check that there's an element in the collection) than to the subscript (trap).

However, it *is* a usability sore spot on collection literals and ranges made 
from literals. Nobody writes [1,2,3].first, because the first element is known. 
However, [1,2,3].randomElement() makes sense (as does (0...6).randomElement()), 
and we know that it has to return a value.

This could be solved with non-type generic parameters and making literals use 
them, but I don't see that happening for Swift 5. I think that I'm favorable to 
having a trapping version of it on ranges that shadows an Optional one that 
comes from a Collection extension until there's a better option.

> Le 5 oct. 2017 à 22:16, David Hart via swift-evolution 
>  a écrit :
> 
> 
> On 6 Oct 2017, at 06:25, David Hart via swift-evolution 
> > wrote:
> 
>> 
>> On 5 Oct 2017, at 20:23, Ben Cohen via swift-evolution 
>> > wrote:
>> 
>>> 
 On Oct 5, 2017, at 10:58, Nate Cook via swift-evolution 
 > wrote:
 
 The edge case is really the same (empty ranges), it’s about what we do 
 with the edge case. If we include the methods on integer types, usage will 
 look like this:
 
 let x = Int.random(in: 0..<5) // 3
 let y = Int.random(in: 0..<0) // runtime error
 
>>> 
>>> These examples are a bit misleading, because they use literals.  Sometimes 
>>> they will, sure, but in practice, many use cases would define 
>>> Int.random(in: 0..>> pitfalls as array.random().
>>> 
>>> p.s. ideally Int.random(in: 0..<0) would be a compile time error...
>>> 
 If we only have the collection methods, usage will look like this:
 
 let x = (0..<5).random()! // 3
 let y = (0..<0).random()! // runtime error
 
>>> 
>>> I don’t know if it’s a given that we must make randomElement optional. I’m 
>>> on the fence as to whether it should be optional vs trap on empty. 
>> 
>> I vote for making them optional because doing otherwise would be 
>> inconsistent with first and last, no?
> 
> I want to be able to check for empty at the same time as I get the value, 
> exactly like I do first first and last:
> 
> if let rand = array.randomElement() {
> // use rand
> } else {
> // handle empty
> }
> 
> OR
> 
> guard let rand = array.randomElement() else {
> // handle empty
> }
> 
> I also like those optional returning properties because it’s a small reminder 
> from the type system to check for the corner case (empty) and makes them 
> explicit when reading code. With a trapping function, I would often forget to 
> handle empty and it wouldn’t jump out at me when reading code.
> 
>>> Another option is to shadow randomElement on closed range to be 
>>> non-optional.
>>> 
 But my suspicion is that lots of people will write things like this:
 
 guard let x = (0..<5).random() 
 else { fatalError("not gonna happen") }
 
 I’d rather have the numeric methods trap than add the optional unwrapping 
 step to every one of these calls. For me, getting a random number and 
 picking a random element of a collection are two different 
 operations—where it’s common to work with empty collections, especially in 
 generic code, trying to get a random value from an empty range is really a 
 programming error. I think it’s okay for them to have slightly different 
 semantics.
 
 Nate
 
 
> On Oct 5, 2017, at 12:27 PM, Alejandro Alonso  > wrote:
> 
> Rather 0 ..< 0 my bad. I think if we include closedcountable, then there 
> needs to be support for countable, but there are edge cases where users 
> can input invalid ranges for countable. 
> 
> Enviado desde mi iPhone
> 
> El oct. 5, 2017, a la(s) 12:22, Alejandro Alonso via swift-evolution 
> > escribió:
> 
>> I agree with Ben here because users can still enter an invalid range 
>> with the static function. I.E. Int.random(in: 0 ... 0). 
>> I would really prefer excluding these static functions from numeric 
>> types.
>> 
>> - Alejandro
>> 
>> El oct. 5, 2017, a la(s) 12:03, Nate Cook via swift-evolution 
>> > escribió:
>> 
 On Oct 5, 2017, at 11:30 AM, Ben Cohen via swift-evolution 
 > wrote:
 
> On Oct 4, 2017, at 9:12 PM, Chris Lattner via swift-evolution 
> 

Re: [swift-evolution] Re-initialization of lazy variables?

2017-10-06 Thread Karl Wagner via swift-evolution


> On 6. Oct 2017, at 14:49, Spencer Kohan via swift-evolution 
>  wrote:
> 
> Hi all,
> 
> In migrating to swift 4 I've noticed one thing which has changed is there is 
> no longer support for the automatic re-initialization of lazy variables.  
> 
> In swift 3 I could declare a variable like this:
> 
> lazy var myVar : MyType! = {
> return makeMyVar()
> }()
> 
> And then if I wanted that initialization block to be executed again, I could 
> just nullify the variable:
> 
> self.myVar = nil
> 
> It looks as if this was never intentional, and according to this bug report 
> , and now the nullified variable stay 
> null rather than executing the initialization block a second time.
> 
> Has the possibility been discussed of providing a way to force lazy vars to 
> initialize more than once?  Working with swift 3 I found this behavior to be 
> very useful in some use cases.  For example in computer graphics it's a nice 
> way to handle the generation of assets which only need to be created in the 
> case of some relatively infrequent event, like for instance a window resize.  
> It seems I'm not alone - the top stack-overflow question 
> 
>  related to re-initializing lazy variables has over 10k views, so I suppose 
> others have found a use case for this functionality as well.
> 
> Cheers,
> Spencer Kohan
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

Yes, the issue has come up before. There is/was a plan to generalise “lazy” as 
some kind of “property behaviour” which could support more advanced 
functionality, such as you described. AFAIK it doesn’t have a specific place on 
the roadmap.

See: 
https://github.com/apple/swift/blob/master/test/Prototypes/property_behaviors/lazy.swift
 


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


Re: [swift-evolution] Fix "private extension" (was "Public Access Modifier Respected in Type Definition")

2017-10-06 Thread Vladimir.S via swift-evolution

On 05.10.2017 20:52, Jose Cheyo Jimenez via swift-evolution wrote:



On Oct 5, 2017, at 4:32 AM, David Hart > wrote:



On 5 Oct 2017, at 07:34, Jose Cheyo Jimenez via swift-evolution > wrote:


I appreciate the enthusiasm but this is not a bug. This was a deliberate change in swift 3 to make `private 
extension` usable. If this was a bug then during swift 3 we should have disallowed `private extension` and only 
allowed `fileprivate extension` but that is not what happened. `private extension` has worked the same since swift 1. 
I’ve always used `private extension` when I want to add methods to String or other build in types. 


It’s not a bug, but its unfortunate the behaviour wasn’t changed at the same time as SE-0169, and it now is very 
inconsistent. I also don’t have to rehash previous discussions, but if a Core Team member (Chris) is okay with going 
ahead with this, perhaps we should consider it.


This could have not been part of 169 because it would've required to lower the 
visibility of the private extension modifier.

“No migration will be necessary as this proposal merely broadens the visibility 
of|private|.”

There was a corner case mentioned when dealing with functions with the same 
name and that was understandable.

private extension is consistent to the way the private scope rules work. The word private is explicit at the top level 
because extensions can only be declared at top level. Top level private is always fileprivate. The inconsistency is that 
we have 1 scope ALC and the rest are not. An explicit declaration should always take precedence when declaring something 
like an access level override.


FWIW, I can't agree with this. 'private extension' is a real point of 
additional confusion for access levels in Swift.
Extension *by itself* has no access level, we only can specify the *default* (and the top most) access level for inner 
methods.

I.e. 'private' access modifier for extension has not the same meaning as 
'private' func/type/variable at file scope.
(Yes, I also believe we should disallow 'private' keyword at file level and allow it only for extensions, so 
'fileprivate' should be used explicitly if one needs this. At least warning should be raised. This is the *root* of the 
problem we discuss now. But unfortunately I don't expect this could be supported.)
The latter is 'direct' access level for the func/type/variable and here we apply the standard rule for scoped private, 
so 'private' for file scope --> 'fileprivate'.


The former means 'the default(and top most) modifier that will be auto-inserted by compiler for all nested methods in 
extension'. This relatively simple rule should not be complicated by additional rule as ", but if it is private 
extension, result access level will be fileprivate, you can't have extensions with private methods"


And, as was already said, this inconsistency leads to *relaxed* access level, which can lead to bugs. If one expects 
'private extension' means 'fileprivate extension' - compiler will show(with error) that this assumption is wrong just 
after the first attempt to access methods from outside of the extended type.
But if one expects true 'private' access level - the methods from private extension could be called from any other code 
in the same file(by mistake, or because code was written a long time ago, or by another developer) and this clearly 
could produce complex bugs.


Also, isn't it a strange code below:

private extension MyType {
  func foo() {}
  private bar() {}
  fileprivate baz() {} // note that "usually" fileprivate is 'wider' access 
level
}

but it has *currently* a sense - 'foo' is fileprivate, and 'bar' is 'true' 
private.
Yes, currently we have a warning about 'baz': "warning: declaring a fileprivate instance method in a private extension", 
but then we have a question "Why?", as private at top level == fileprivate. and this does not produce any warnings:

fileprivate extension MyType {
fileprivate func foo() {}
}

Even more, someone can think "why we need 'private' declaration in private extension, probably this is a mistake i.e. 
unnecessary duplication of code, I'll refactor this and delete this explicit 'private' because extension is already 
private' and so will open doors for future problems.


So I do believe we really need to remove that ugly inconsistency and make Swift better to write, understand and support 
the code.


Vladimir.





private is different because it is scoped so because of that it is also different when dealing with extensions. Top 
level private is always the same as fileprivate thanks to its scoped nature.


Making private the scope ACL was a mistake but that ship has sailed and so has 
this one imo.



On Oct 4, 2017, at 10:05 PM, Tony Allevato > wrote:

Trust me, I'm the last person who wants to 

[swift-evolution] Re-initialization of lazy variables?

2017-10-06 Thread Spencer Kohan via swift-evolution
Hi all,

In migrating to swift 4 I've noticed one thing which has changed is there
is no longer support for the automatic re-initialization of lazy
variables.

In swift 3 I could declare a variable like this:

lazy var myVar : MyType! = {
return makeMyVar()
}()

And then if I wanted that initialization block to be executed again, I
could just nullify the variable:

self.myVar = nil

It looks as if this was never intentional, and according to this bug report
, and now the nullified variable
stay null rather than executing the initialization block a second time.

Has the possibility been discussed of providing a way to force lazy vars to
initialize more than once?  Working with swift 3 I found this behavior to
be very useful in some use cases.  For example in computer graphics it's a
nice way to handle the generation of assets which only need to be created
in the case of some relatively infrequent event, like for instance a window
resize.  It seems I'm not alone - the top stack-overflow question

related to re-initializing lazy variables has over 10k views, so I suppose
others have found a use case for this functionality as well.

Cheers,
Spencer Kohan
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Pitch: Cross-module inlining and specialization

2017-10-06 Thread Slava Pestov via swift-evolution
Hi all,

Summarizing the thread so far, I see there were three main points of discussion:

- The name itself, @inlinable, is causing some confusion. Chris suggested a 
more general name, like @fragile. A few other possible names were discussed. I 
don’t think we’ve decided on the best name yet so I’m open to suggestions here. 
I personally like the name @fragile if nobody has objections to it, at the very 
least because it does not mislead the reader into thinking inlining is going to 
take place.

- Several people would like to see @_versioned be formalized (with a better 
name) and added to the proposal. My preference would be to do this in a 
separate proposal soon after, but I’d be willing to entertain the possibility 
of rolling it into this one.

- The core point is whether inlinable functions should retain a public entry 
point in the original module, or if the compiler should always be required to 
emit a copy (whether inlined or not) into the client module. Joe Groff made a 
number of good arguments in favor of the latter.

Jordan Rose also pointed out offline that we should not allow @inlinable to be 
applied to dynamic methods, since there’s no way for a client to devirtualize 
across an objc_msgSend boundary, so the attribute would have no effect in this 
case. I don’t expect this change to be controversial.

I’d like to get the proposal into a form suitable for publishing as a draft 
pull request against the evolution repository. Do we have some general 
agreement on resolving the above issues, or does anyone still have concerns or 
further suggestions?

Slava

> On Oct 2, 2017, at 1:31 PM, Slava Pestov  wrote:
> 
> Hi all,
> 
> Here is a draft proposal that makes public a feature we’ve had for a while. 
> Let me know what you think!
> 
> Cross-module inlining and specialization ("@inlinable")
> Proposal: SE- 
> Authors: Slava Pestov , Jordan Rose 
> 
> Review Manager: TBD
> Status: Initial pitch
> Implementation: Already implemented as an underscored attribute @_inlineable
> Introduction
> We propose introducing an @inlinable attribute which exports the body of a 
> function as part of a module's interface, making it available to the 
> optimizer when referenced from other modules.
> 
> Motivation
> One of the top priorities of the Swift 5 release is a design and 
> implementation of the Swift ABI. This effort consists of three major tasks:
> 
> Finalizing the low-level function calling convention, layout of data types, 
> and various runtime data structures. The goal here is to maintain 
> compatibility across compiler versions, ensuring that we can continue to make 
> improvements to the Swift compiler without breaking binaries built with an 
> older version of the compiler.
> 
> Implementing support for library evolution, or the ability to make certain 
> source-compatible changes, without breaking binary compatibility. Examples of 
> source-compatible changes we are considering include adding new stored 
> properties to structs and classes, removing private stored properties from 
> structs and classes, adding new public methods to a class, or adding new 
> protocol requirements that have a default implementation. The goal here is to 
> maintain compatibility across framework versions, ensuring that framework 
> authors can evolve their API without breaking binaries built against an older 
> version of the framework. For more information about the resilience model, 
> see the library evolution document 
>  in the 
> Swift repository.
> 
> Stabilizing the API of the standard library. The goal here is to ensure that 
> the standard library can be deployed separately from client binaries and 
> frameworks, without forcing recompilation of existing code.
> 
> All existing language features of Swift were designed with these goals in 
> mind. In particular, the implementation of generic types and functions relies 
> on runtime reified types to allow separate compilation and type checking of 
> generic code.
> 
> Within the scope of a single module, the Swift compiler performs very 
> aggressive optimization, including full and partial specialization of generic 
> functions, inlining, and various forms of interprocedural analysis.
> 
> On the other hand, across module boundaries, runtime generics introduce 
> unavoidable overhead, as reified type metadata must be passed between 
> functions, and various indirect access patterns must be used to manipulate 
> values of generic type. We believe that for most applications, this overhead 
> is negligible compared to the actual work performed by the code itself.
> 
> However, for some advanced use cases, and in particular for the standard 
> library, the overhead of runtime generics can dominate any useful work 
> performed by the library. Examples include the various algorithms defined in 
>