Re: [swift-evolution] [Draft] Introducing StaticSelf, an Invariant Self

2016-05-19 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On May 19, 2016, at 3:14 AM, L. Mihalkovic  
> wrote:
> 
> It strikes me that in a sense, the proposed StaticSelf is basically what  '_' 
> does
> 
> By specifying StaticSelf we are trying to tell the compiler to ignore what is 
> going on that that precise location to revert to something expressed 
> 'earlier'. This is somehwat anologous to what we do when we use '_' in 
> signatures: we escape the specifics of the current location, ony in that case 
> there is no prior context to refer to, so the parameter winds up having no 
> particular name.
> 
> If you try to read the examples with this interpretation: "nothing specific 
> from this location" then you can see how you wind up 'inheriting' the 
> previously expressed static type of self. So I would seriously consider using 
> _ instead of adding StaticSelf.

This proposal is no longer being pursued.  Please have a look at the solution 
that has been identified if you're interested.

> 
> 
> Regards
> (From mobile)
> 
>> On May 18, 2016, at 7:37 PM, Erica Sadun via swift-evolution 
>>  wrote:
>> 
>> As a wrap-up of the topic, I've updated our original draft with Nicola S's 
>> resolution.
>> 
>> https://gist.github.com/erica/995af96a0de2f2f3dc419935e8140927
>> 
>> -- E
>> 
>> 
 On May 14, 2016, at 8:35 AM, Matthew Johnson via swift-evolution 
  wrote:
 
 
 On May 14, 2016, at 12:55 AM, Nicola Salmoria via swift-evolution 
  wrote:
 
 Matthew Johnson via swift-evolution  writes:
 
> I agree it’s a bit tricky.  But that’s better than not possible at all.
 You just need a typealias and a same type constraint to make this work as
 expected / desired:
> 
> 
> protocol Makable {
> 
>   typealias RootMakable = StaticSelf
>   static func make(value: Int) -> StaticSelf
> }
> 
> func makeWithZero(x: Int) -> T {
>   return T.make(value: 0) // works now
> }
> 
> 
> Now that we have a typealias we can refer to the binding of StaticSelf and
 constrain it as necessary for whatever purpose we have in mind.  In some
 cases that will be a same type constraint so that our code works properly
 with class clusters.  I don’t have concrete examples of other use cases but
 can imagine use cases constraining the typealias to a protocol, for 
 example.
 
 You can do that today:
 
 protocol Makable {
   associatedtype MadeType
   static func make(value: Int) -> MadeType
 }
 
 func makeWithZero(x: Int) -> T {
   return T.make(value: 0)
 }
 
 You can't currently constrain MadeType to be the same as the conforming
 type, but, does it matter? What kind of extra guarantees would that give,
 since you need to add the extra constraint anyway in generic code?
>>> 
>>> Wow, this is pretty cool.  Thank you very much for pointing this out Nicola!
>>> 
>>> I haven’t seen this approach to solving the problem.  Given the amount of 
>>> discussion this problem has received I am surprised nobody has shared this 
>>> solution yet.  I just checked in Xcode 7.3 and it works there.  It isn’t 
>>> dependent on any pre-release features.  
>>> 
>>> Instead of using StaticSelf under the current proposal:
>>> 
>>> protocol StringInitializable {
>>>static func initializeWith(string: String) -> StaticSelf
>>> }
>>> 
>>> We just add an associatedtype defaulted to Self:
>>> 
>>> protocol StringInitializable {
>>>associatedtype Initialized = Self // where Self: Initialized
>>>static func initializeWith(string: String) -> Initialized
>>> }
>>> 
>>> extension NSURL: StringInitializable {
>>>static func initializeWith(string: String) -> NSURL {
>>>return NSURL()
>>>}
>>> }
>>> 
>>> func makeWith(string: 
>>> String) -> T {
>>>return T.initializeWith(string: string)
>>> }
>>> 
>>> There are two minor downsides to this approach:
>>> 
>>> 1. You can’t copy and paste the method signature.
>>> 2. You can theoretically conform a type completely unrelated to 
>>> `Initialized` to the protocol, thus violating the semantics.
>>> 
>>> I think we can live with these downsides.  Maybe the `Self: Initialized` 
>>> will be possible someday.  That would be pretty close to StaticSelf.  The 
>>> only difference would be that subclasses still have flexibility to override 
>>> with their own type.
>>> 
>>> Now that a reasonable way to do this with existing language features has 
>>> been identified I will withdraw this proposal.   If this approach doesn’t 
>>> address use cases others have in mind for StaticSelf please speak up!
>>> 
>>> Doug, if you’re reading this, does the `where Self: Initialized` (i.e. 
>>> arbitrary subclass constraints) fall into the scope of your “completing 
>>> generics” manifesto?  This is a concrete use case that would utilize 
>>> 

Re: [swift-evolution] [Draft] Introducing StaticSelf, an Invariant Self

2016-05-19 Thread L. Mihalkovic via swift-evolution
It strikes me that in a sense, the proposed StaticSelf is basically what  '_' 
does

By specifying StaticSelf we are trying to tell the compiler to ignore what is 
going on that that precise location to revert to something expressed 'earlier'. 
This is somehwat anologous to what we do when we use '_' in signatures: we 
escape the specifics of the current location, ony in that case there is no 
prior context to refer to, so the parameter winds up having no particular name.

If you try to read the examples with this interpretation: "nothing specific 
from this location" then you can see how you wind up 'inheriting' the 
previously expressed static type of self. So I would seriously consider using _ 
instead of adding StaticSelf.


Regards
(From mobile)

> On May 18, 2016, at 7:37 PM, Erica Sadun via swift-evolution 
>  wrote:
> 
> As a wrap-up of the topic, I've updated our original draft with Nicola S's 
> resolution.
> 
> https://gist.github.com/erica/995af96a0de2f2f3dc419935e8140927
> 
> -- E
> 
> 
>>> On May 14, 2016, at 8:35 AM, Matthew Johnson via swift-evolution 
>>>  wrote:
>>> 
>>> 
>>> On May 14, 2016, at 12:55 AM, Nicola Salmoria via swift-evolution 
>>>  wrote:
>>> 
>>> Matthew Johnson via swift-evolution  writes:
>>> 
 I agree it’s a bit tricky.  But that’s better than not possible at all.
>>> You just need a typealias and a same type constraint to make this work as
>>> expected / desired:
 
 
 protocol Makable {
 
typealias RootMakable = StaticSelf
static func make(value: Int) -> StaticSelf
 }
 
 func makeWithZero(x: Int) -> T {
return T.make(value: 0) // works now
 }
 
 
 Now that we have a typealias we can refer to the binding of StaticSelf and
>>> constrain it as necessary for whatever purpose we have in mind.  In some
>>> cases that will be a same type constraint so that our code works properly
>>> with class clusters.  I don’t have concrete examples of other use cases but
>>> can imagine use cases constraining the typealias to a protocol, for example.
>>> 
>>> You can do that today:
>>> 
>>> protocol Makable {
>>>   associatedtype MadeType
>>>   static func make(value: Int) -> MadeType
>>> }
>>> 
>>> func makeWithZero(x: Int) -> T {
>>>   return T.make(value: 0)
>>> }
>>> 
>>> You can't currently constrain MadeType to be the same as the conforming
>>> type, but, does it matter? What kind of extra guarantees would that give,
>>> since you need to add the extra constraint anyway in generic code?
>> 
>> Wow, this is pretty cool.  Thank you very much for pointing this out Nicola!
>> 
>> I haven’t seen this approach to solving the problem.  Given the amount of 
>> discussion this problem has received I am surprised nobody has shared this 
>> solution yet.  I just checked in Xcode 7.3 and it works there.  It isn’t 
>> dependent on any pre-release features.  
>> 
>> Instead of using StaticSelf under the current proposal:
>> 
>> protocol StringInitializable {
>>static func initializeWith(string: String) -> StaticSelf
>> }
>> 
>> We just add an associatedtype defaulted to Self:
>> 
>> protocol StringInitializable {
>>associatedtype Initialized = Self // where Self: Initialized
>>static func initializeWith(string: String) -> Initialized
>> }
>> 
>> extension NSURL: StringInitializable {
>>static func initializeWith(string: String) -> NSURL {
>>return NSURL()
>>}
>> }
>> 
>> func makeWith(string: 
>> String) -> T {
>>return T.initializeWith(string: string)
>> }
>> 
>> There are two minor downsides to this approach:
>> 
>> 1. You can’t copy and paste the method signature.
>> 2. You can theoretically conform a type completely unrelated to 
>> `Initialized` to the protocol, thus violating the semantics.
>> 
>> I think we can live with these downsides.  Maybe the `Self: Initialized` 
>> will be possible someday.  That would be pretty close to StaticSelf.  The 
>> only difference would be that subclasses still have flexibility to override 
>> with their own type.
>> 
>> Now that a reasonable way to do this with existing language features has 
>> been identified I will withdraw this proposal.   If this approach doesn’t 
>> address use cases others have in mind for StaticSelf please speak up!
>> 
>> Doug, if you’re reading this, does the `where Self: Initialized` (i.e. 
>> arbitrary subclass constraints) fall into the scope of your “completing 
>> generics” manifesto?  This is a concrete use case that would utilize 
>> subclass constraints.
>> 
>> -Matthew
>> 
>> 
>>> 
>>> Nicola
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> 

Re: [swift-evolution] [Draft] Introducing StaticSelf, an Invariant Self

2016-05-18 Thread Thorsten Seitz via swift-evolution
Geeat solution! Thanks to Nicola for posting it!

> Am 14.05.2016 um 16:35 schrieb Matthew Johnson via swift-evolution 
> :
> 
> 
>> On May 14, 2016, at 12:55 AM, Nicola Salmoria via swift-evolution 
>>  wrote:
>> 
>> Matthew Johnson via swift-evolution  writes:
>> 
>>> I agree it’s a bit tricky.  But that’s better than not possible at all.
>> You just need a typealias and a same type constraint to make this work as
>> expected / desired:
>>> 
>>> 
>>> protocol Makable {
>>> 
>>>typealias RootMakable = StaticSelf
>>>static func make(value: Int) -> StaticSelf
>>> }
>>> 
>>> func makeWithZero(x: Int) -> T {
>>>return T.make(value: 0) // works now
>>> }
>>> 
>>> 
>>> Now that we have a typealias we can refer to the binding of StaticSelf and
>> constrain it as necessary for whatever purpose we have in mind.  In some
>> cases that will be a same type constraint so that our code works properly
>> with class clusters.  I don’t have concrete examples of other use cases but
>> can imagine use cases constraining the typealias to a protocol, for example.
>> 
>> You can do that today:
>> 
>> protocol Makable {
>>   associatedtype MadeType
>>   static func make(value: Int) -> MadeType
>> }
>> 
>> func makeWithZero(x: Int) -> T {
>>   return T.make(value: 0)
>> }
>> 
>> You can't currently constrain MadeType to be the same as the conforming
>> type, but, does it matter? What kind of extra guarantees would that give,
>> since you need to add the extra constraint anyway in generic code?
> 
> Wow, this is pretty cool.  Thank you very much for pointing this out Nicola!
> 
> I haven’t seen this approach to solving the problem.  Given the amount of 
> discussion this problem has received I am surprised nobody has shared this 
> solution yet.  I just checked in Xcode 7.3 and it works there.  It isn’t 
> dependent on any pre-release features.  
> 
> Instead of using StaticSelf under the current proposal:
> 
> protocol StringInitializable {
>static func initializeWith(string: String) -> StaticSelf
> }
> 
> We just add an associatedtype defaulted to Self:
> 
> protocol StringInitializable {
>associatedtype Initialized = Self // where Self: Initialized
>static func initializeWith(string: String) -> Initialized
> }
> 
> extension NSURL: StringInitializable {
>static func initializeWith(string: String) -> NSURL {
>return NSURL()
>}
> }
> 
> func makeWith(string: 
> String) -> T {
>return T.initializeWith(string: string)
> }
> 
> There are two minor downsides to this approach:
> 
> 1. You can’t copy and paste the method signature.
> 2. You can theoretically conform a type completely unrelated to `Initialized` 
> to the protocol, thus violating the semantics.
> 
> I think we can live with these downsides.  Maybe the `Self: Initialized` will 
> be possible someday.  That would be pretty close to StaticSelf.  The only 
> difference would be that subclasses still have flexibility to override with 
> their own type.
> 
> Now that a reasonable way to do this with existing language features has been 
> identified I will withdraw this proposal.   If this approach doesn’t address 
> use cases others have in mind for StaticSelf please speak up!
> 
> Doug, if you’re reading this, does the `where Self: Initialized` (i.e. 
> arbitrary subclass constraints) fall into the scope of your “completing 
> generics” manifesto?  This is a concrete use case that would utilize subclass 
> constraints.

+1 for being able to constrain the generic type. I've been missing that in my 
little graph library.

-Thorsten 

> 
> -Matthew
> 
> 
>> 
>> Nicola
>> ___
>> 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] [Draft] Introducing StaticSelf, an Invariant Self

2016-05-18 Thread Patrick Smith via swift-evolution
Oh yep, I accidentally read that section as ‘Alternatives Considered’.

I still find this a little bit of a hack, so I hope this approach doesn’t get 
used too much, certainly not in the standard library. Is this only useful for 
factory or other static methods? It would just be a shame to see protocols 
become defensive for use cases like this.

I believe the protocol should remain ‘pure’, and the conforming types then 
decide on which way they want to go. If they use a static type (or label the 
method final), then its particular protocol requirements change.

Anyway, nice resolution!


> On 19 May 2016, at 1:06 PM, Matthew Johnson  wrote:
> 
> 
> 
> Sent from my iPad
> 
> On May 18, 2016, at 9:57 PM, Patrick Smith  > wrote:
> 
>> I think the distinction between StaticSelf and Self will be very confusing 
>> to newcomers.
>> 
>> So the only reason why we must use StaticSelf instead of Self here is 
>> because we want NSURL to conform, and it isn’t final?
>> 
>> protocol StringCreatable {
>> static func createWithString(s: String) -> StaticSelf
>> }
>> 
>> I find it a code smell that this would affect the protocol and not the class.
>> 
>> Why couldn’t you have this?
>> 
>> protocol StringCreatable {
>> static func createWithString(s: String) -> Self
>> }
>> 
>> extension NSURL: StringCreatable {
>>  // can now conform conform because NSURL is fixed and matches the static
>>  // type of the conforming construct. Subclasses need not re-implement
>>  // NOTE: the return type can be declared as StaticSelf *or* as NSURL
>>  //   they are interchangeable
>>  static func createWithString(s: String) -> StaticSelf { 
>>  // ...
>>  }
>> }
>> 
> 
> You can't do this because the Self return type in the protocol requirement 
> specifically *requires* all subclasses to override the method and return an 
> instance of the subclass type.  
> 
> Nevertheless, we have identified a workaround that is similar enough to 
> StaticSelf that we have abandoned the proposal.  Please see The last couple 
> posts in this thread if you're interested in the details.
> 
>> 
>> 
>>> On 19 May 2016, at 3:37 AM, Erica Sadun via swift-evolution 
>>> > wrote:
>>> 
>>> As a wrap-up of the topic, I've updated our original draft with Nicola S's 
>>> resolution.
>>> 
>>> https://gist.github.com/erica/995af96a0de2f2f3dc419935e8140927 
>>> 
>>> 
>>> -- E
>>> 
>>> 
 On May 14, 2016, at 8:35 AM, Matthew Johnson via swift-evolution 
 > wrote:
 
> 
> On May 14, 2016, at 12:55 AM, Nicola Salmoria via swift-evolution 
> > wrote:
> 
> Matthew Johnson via swift-evolution  writes:
> 
>> I agree it’s a bit tricky.  But that’s better than not possible at all.
> You just need a typealias and a same type constraint to make this work as
> expected / desired:
>> 
>> 
>> protocol Makable {
>> 
>>  typealias RootMakable = StaticSelf
>>  static func make(value: Int) -> StaticSelf
>> }
>> 
>> func makeWithZero(x: Int) -> T {
>>  return T.make(value: 0) // works now
>> }
>> 
>> 
>> Now that we have a typealias we can refer to the binding of StaticSelf 
>> and
> constrain it as necessary for whatever purpose we have in mind.  In some
> cases that will be a same type constraint so that our code works properly
> with class clusters.  I don’t have concrete examples of other use cases 
> but
> can imagine use cases constraining the typealias to a protocol, for 
> example.
> 
> You can do that today:
> 
> protocol Makable {
>   associatedtype MadeType
>   static func make(value: Int) -> MadeType
> }
> 
> func makeWithZero(x: Int) -> T {
>   return T.make(value: 0)
> }
> 
> You can't currently constrain MadeType to be the same as the conforming
> type, but, does it matter? What kind of extra guarantees would that give,
> since you need to add the extra constraint anyway in generic code?
 
 Wow, this is pretty cool.  Thank you very much for pointing this out 
 Nicola!
 
 I haven’t seen this approach to solving the problem.  Given the amount of 
 discussion this problem has received I am surprised nobody has shared this 
 solution yet.  I just checked in Xcode 7.3 and it works there.  It isn’t 
 dependent on any pre-release features.  
 
 Instead of using StaticSelf under the current proposal:
 
 protocol StringInitializable {
static func initializeWith(string: String) -> StaticSelf
 }
 
 We just add an associatedtype defaulted to Self:
 
 protocol 

Re: [swift-evolution] [Draft] Introducing StaticSelf, an Invariant Self

2016-05-18 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On May 18, 2016, at 9:57 PM, Patrick Smith  wrote:
> 
> I think the distinction between StaticSelf and Self will be very confusing to 
> newcomers.
> 
> So the only reason why we must use StaticSelf instead of Self here is because 
> we want NSURL to conform, and it isn’t final?
> 
> protocol StringCreatable {
> static func createWithString(s: String) -> StaticSelf
> }
> 
> I find it a code smell that this would affect the protocol and not the class.
> 
> Why couldn’t you have this?
> 
> protocol StringCreatable {
> static func createWithString(s: String) -> Self
> }
> 
> extension NSURL: StringCreatable {
>  // can now conform conform because NSURL is fixed and matches the static
>  // type of the conforming construct. Subclasses need not re-implement
>  // NOTE: the return type can be declared as StaticSelf *or* as NSURL
>  //   they are interchangeable
>  static func createWithString(s: String) -> StaticSelf { 
>  // ...
>  }
> }
> 

You can't do this because the Self return type in the protocol requirement 
specifically *requires* all subclasses to override the method and return an 
instance of the subclass type.  

Nevertheless, we have identified a workaround that is similar enough to 
StaticSelf that we have abandoned the proposal.  Please see The last couple 
posts in this thread if you're interested in the details.

> 
> 
>> On 19 May 2016, at 3:37 AM, Erica Sadun via swift-evolution 
>>  wrote:
>> 
>> As a wrap-up of the topic, I've updated our original draft with Nicola S's 
>> resolution.
>> 
>> https://gist.github.com/erica/995af96a0de2f2f3dc419935e8140927
>> 
>> -- E
>> 
>> 
 On May 14, 2016, at 8:35 AM, Matthew Johnson via swift-evolution 
  wrote:
 
 
 On May 14, 2016, at 12:55 AM, Nicola Salmoria via swift-evolution 
  wrote:
 
 Matthew Johnson via swift-evolution  writes:
 
> I agree it’s a bit tricky.  But that’s better than not possible at all.
 You just need a typealias and a same type constraint to make this work as
 expected / desired:
> 
> 
> protocol Makable {
> 
>   typealias RootMakable = StaticSelf
>   static func make(value: Int) -> StaticSelf
> }
> 
> func makeWithZero(x: Int) -> T {
>   return T.make(value: 0) // works now
> }
> 
> 
> Now that we have a typealias we can refer to the binding of StaticSelf and
 constrain it as necessary for whatever purpose we have in mind.  In some
 cases that will be a same type constraint so that our code works properly
 with class clusters.  I don’t have concrete examples of other use cases but
 can imagine use cases constraining the typealias to a protocol, for 
 example.
 
 You can do that today:
 
 protocol Makable {
   associatedtype MadeType
   static func make(value: Int) -> MadeType
 }
 
 func makeWithZero(x: Int) -> T {
   return T.make(value: 0)
 }
 
 You can't currently constrain MadeType to be the same as the conforming
 type, but, does it matter? What kind of extra guarantees would that give,
 since you need to add the extra constraint anyway in generic code?
>>> 
>>> Wow, this is pretty cool.  Thank you very much for pointing this out Nicola!
>>> 
>>> I haven’t seen this approach to solving the problem.  Given the amount of 
>>> discussion this problem has received I am surprised nobody has shared this 
>>> solution yet.  I just checked in Xcode 7.3 and it works there.  It isn’t 
>>> dependent on any pre-release features.  
>>> 
>>> Instead of using StaticSelf under the current proposal:
>>> 
>>> protocol StringInitializable {
>>>static func initializeWith(string: String) -> StaticSelf
>>> }
>>> 
>>> We just add an associatedtype defaulted to Self:
>>> 
>>> protocol StringInitializable {
>>>associatedtype Initialized = Self // where Self: Initialized
>>>static func initializeWith(string: String) -> Initialized
>>> }
>>> 
>>> extension NSURL: StringInitializable {
>>>static func initializeWith(string: String) -> NSURL {
>>>return NSURL()
>>>}
>>> }
>>> 
>>> func makeWith(string: 
>>> String) -> T {
>>>return T.initializeWith(string: string)
>>> }
>>> 
>>> There are two minor downsides to this approach:
>>> 
>>> 1. You can’t copy and paste the method signature.
>>> 2. You can theoretically conform a type completely unrelated to 
>>> `Initialized` to the protocol, thus violating the semantics.
>>> 
>>> I think we can live with these downsides.  Maybe the `Self: Initialized` 
>>> will be possible someday.  That would be pretty close to StaticSelf.  The 
>>> only difference would be that subclasses still have flexibility to override 
>>> with their own type.
>>> 
>>> Now that a reasonable way to do this with existing language features has 
>>> been identified I 

Re: [swift-evolution] [Draft] Introducing StaticSelf, an Invariant Self

2016-05-18 Thread Patrick Smith via swift-evolution
I think the distinction between StaticSelf and Self will be very confusing to 
newcomers.

So the only reason why we must use StaticSelf instead of Self here is because 
we want NSURL to conform, and it isn’t final?

protocol StringCreatable {
static func createWithString(s: String) -> StaticSelf
}

I find it a code smell that this would affect the protocol and not the class.

Why couldn’t you have this?

protocol StringCreatable {
static func createWithString(s: String) -> Self
}

extension NSURL: StringCreatable {
 // can now conform conform because NSURL is fixed and matches the static
 // type of the conforming construct. Subclasses need not re-implement
 // NOTE: the return type can be declared as StaticSelf *or* as NSURL
 //   they are interchangeable
 static func createWithString(s: String) -> StaticSelf { 
 // ...
 }
}



> On 19 May 2016, at 3:37 AM, Erica Sadun via swift-evolution 
>  wrote:
> 
> As a wrap-up of the topic, I've updated our original draft with Nicola S's 
> resolution.
> 
> https://gist.github.com/erica/995af96a0de2f2f3dc419935e8140927 
> 
> 
> -- E
> 
> 
>> On May 14, 2016, at 8:35 AM, Matthew Johnson via swift-evolution 
>> > wrote:
>> 
>>> 
>>> On May 14, 2016, at 12:55 AM, Nicola Salmoria via swift-evolution 
>>> > wrote:
>>> 
>>> Matthew Johnson via swift-evolution  writes:
>>> 
 I agree it’s a bit tricky.  But that’s better than not possible at all.
>>> You just need a typealias and a same type constraint to make this work as
>>> expected / desired:
 
 
 protocol Makable {
 
typealias RootMakable = StaticSelf
static func make(value: Int) -> StaticSelf
 }
 
 func makeWithZero(x: Int) -> T {
return T.make(value: 0) // works now
 }
 
 
 Now that we have a typealias we can refer to the binding of StaticSelf and
>>> constrain it as necessary for whatever purpose we have in mind.  In some
>>> cases that will be a same type constraint so that our code works properly
>>> with class clusters.  I don’t have concrete examples of other use cases but
>>> can imagine use cases constraining the typealias to a protocol, for example.
>>> 
>>> You can do that today:
>>> 
>>> protocol Makable {
>>>   associatedtype MadeType
>>>   static func make(value: Int) -> MadeType
>>> }
>>> 
>>> func makeWithZero(x: Int) -> T {
>>>   return T.make(value: 0)
>>> }
>>> 
>>> You can't currently constrain MadeType to be the same as the conforming
>>> type, but, does it matter? What kind of extra guarantees would that give,
>>> since you need to add the extra constraint anyway in generic code?
>> 
>> Wow, this is pretty cool.  Thank you very much for pointing this out Nicola!
>> 
>> I haven’t seen this approach to solving the problem.  Given the amount of 
>> discussion this problem has received I am surprised nobody has shared this 
>> solution yet.  I just checked in Xcode 7.3 and it works there.  It isn’t 
>> dependent on any pre-release features.  
>> 
>> Instead of using StaticSelf under the current proposal:
>> 
>> protocol StringInitializable {
>>static func initializeWith(string: String) -> StaticSelf
>> }
>> 
>> We just add an associatedtype defaulted to Self:
>> 
>> protocol StringInitializable {
>>associatedtype Initialized = Self // where Self: Initialized
>>static func initializeWith(string: String) -> Initialized
>> }
>> 
>> extension NSURL: StringInitializable {
>>static func initializeWith(string: String) -> NSURL {
>>return NSURL()
>>}
>> }
>> 
>> func makeWith(string: 
>> String) -> T {
>>return T.initializeWith(string: string)
>> }
>> 
>> There are two minor downsides to this approach:
>> 
>> 1. You can’t copy and paste the method signature.
>> 2. You can theoretically conform a type completely unrelated to 
>> `Initialized` to the protocol, thus violating the semantics.
>> 
>> I think we can live with these downsides.  Maybe the `Self: Initialized` 
>> will be possible someday.  That would be pretty close to StaticSelf.  The 
>> only difference would be that subclasses still have flexibility to override 
>> with their own type.
>> 
>> Now that a reasonable way to do this with existing language features has 
>> been identified I will withdraw this proposal.   If this approach doesn’t 
>> address use cases others have in mind for StaticSelf please speak up!
>> 
>> Doug, if you’re reading this, does the `where Self: Initialized` (i.e. 
>> arbitrary subclass constraints) fall into the scope of your “completing 
>> generics” manifesto?  This is a concrete use case that would utilize 
>> subclass constraints.
>> 
>> -Matthew
>> 
>> 
>>> 
>>> Nicola
>>> ___
>>> swift-evolution mailing list
>>> 

Re: [swift-evolution] [Draft] Introducing StaticSelf, an Invariant Self

2016-05-18 Thread Erica Sadun via swift-evolution
As a wrap-up of the topic, I've updated our original draft with Nicola S's 
resolution.

https://gist.github.com/erica/995af96a0de2f2f3dc419935e8140927

-- E


> On May 14, 2016, at 8:35 AM, Matthew Johnson via swift-evolution 
>  wrote:
> 
>> 
>> On May 14, 2016, at 12:55 AM, Nicola Salmoria via swift-evolution 
>>  wrote:
>> 
>> Matthew Johnson via swift-evolution  writes:
>> 
>>> I agree it’s a bit tricky.  But that’s better than not possible at all.
>> You just need a typealias and a same type constraint to make this work as
>> expected / desired:
>>> 
>>> 
>>> protocol Makable {
>>> 
>>> typealias RootMakable = StaticSelf
>>> static func make(value: Int) -> StaticSelf
>>> }
>>> 
>>> func makeWithZero(x: Int) -> T {
>>> return T.make(value: 0) // works now
>>> }
>>> 
>>> 
>>> Now that we have a typealias we can refer to the binding of StaticSelf and
>> constrain it as necessary for whatever purpose we have in mind.  In some
>> cases that will be a same type constraint so that our code works properly
>> with class clusters.  I don’t have concrete examples of other use cases but
>> can imagine use cases constraining the typealias to a protocol, for example.
>> 
>> You can do that today:
>> 
>> protocol Makable {
>>   associatedtype MadeType
>>   static func make(value: Int) -> MadeType
>> }
>> 
>> func makeWithZero(x: Int) -> T {
>>   return T.make(value: 0)
>> }
>> 
>> You can't currently constrain MadeType to be the same as the conforming
>> type, but, does it matter? What kind of extra guarantees would that give,
>> since you need to add the extra constraint anyway in generic code?
> 
> Wow, this is pretty cool.  Thank you very much for pointing this out Nicola!
> 
> I haven’t seen this approach to solving the problem.  Given the amount of 
> discussion this problem has received I am surprised nobody has shared this 
> solution yet.  I just checked in Xcode 7.3 and it works there.  It isn’t 
> dependent on any pre-release features.  
> 
> Instead of using StaticSelf under the current proposal:
> 
> protocol StringInitializable {
>static func initializeWith(string: String) -> StaticSelf
> }
> 
> We just add an associatedtype defaulted to Self:
> 
> protocol StringInitializable {
>associatedtype Initialized = Self // where Self: Initialized
>static func initializeWith(string: String) -> Initialized
> }
> 
> extension NSURL: StringInitializable {
>static func initializeWith(string: String) -> NSURL {
>return NSURL()
>}
> }
> 
> func makeWith(string: 
> String) -> T {
>return T.initializeWith(string: string)
> }
> 
> There are two minor downsides to this approach:
> 
> 1. You can’t copy and paste the method signature.
> 2. You can theoretically conform a type completely unrelated to `Initialized` 
> to the protocol, thus violating the semantics.
> 
> I think we can live with these downsides.  Maybe the `Self: Initialized` will 
> be possible someday.  That would be pretty close to StaticSelf.  The only 
> difference would be that subclasses still have flexibility to override with 
> their own type.
> 
> Now that a reasonable way to do this with existing language features has been 
> identified I will withdraw this proposal.   If this approach doesn’t address 
> use cases others have in mind for StaticSelf please speak up!
> 
> Doug, if you’re reading this, does the `where Self: Initialized` (i.e. 
> arbitrary subclass constraints) fall into the scope of your “completing 
> generics” manifesto?  This is a concrete use case that would utilize subclass 
> constraints.
> 
> -Matthew
> 
> 
>> 
>> Nicola
>> ___
>> 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] [Draft] Introducing StaticSelf, an Invariant Self

2016-05-14 Thread Austin Zheng via swift-evolution
I'm not quite sure I understand the 'Additional Utility' section. A given class 
hierarchy can only have one implementation of a given static method; static  
methods are effectively final. Therefore, the 'Self' introduced in the previous 
proposal should be completely sufficient for invoking a static method on a 
class. (Likewise, for moving around code.) In fact, the previous proposal for 
'Self' used a very similar example.

I think the example would make more sense if it involved class methods. 
However, *without considering the protocol applications* I wouldn't consider 
that a compelling enough use case, by itself, to add StaticSelf.

As for StaticSelf's impact on protocols, I defer to the opinions of the other 
folks who've commented on the thread.

Austin


> On May 12, 2016, at 5:49 PM, Matthew Johnson via swift-evolution 
>  wrote:
> 
> Erica Sadun and I have written a proposal are following up the recent 
> discussion thread "[RFC] #Self” with a proposal to introduce StaticSelf, an 
> invariant Self.
> 
> The recent discussion can be found here: 
> http://thread.gmane.org/gmane.comp.lang.swift.evolution/16565 
> 
> 
> The proposal can be found here: 
> https://github.com/anandabits/swift-evolution/blob/static-self/proposals/-static-self.md
>  
> 
> 
> We look forward to continuing the discussion.  We plan to submit a PR in the 
> near future after incorporating your final feedback.
> 
> Thanks,
> Matthew
> Introducing StaticSelf, an Invariant Self
> 
> Proposal: TBD
> Authors: Matthew Johnson , Erica Sadun 
> 
> Status: TBD
> Review manager: TBD
> Introduction
> 
> This proposal introduces a new keyword that provides consistent invariant 
> type semantics in all contexts.
> 
> The Swift-evolution thread about this topic can be found here: [RFC] #Self 
> 
> Motivation
> 
> The distinction between covariant and non-covariant type references come into 
> play when
> conforming non-final classes to protocols. Fixing a protocol requirement to a 
> covarying type
> means that a method returning Self must be overriden by all subclasses in 
> order to return
> the correct, matching type.
> 
> This proposal builds on the covariant construct Self accepted in SE–0068 
> 
> to introduce an invariant type identifier. It enables protocol declarations 
> to consistently
> refer to a type that is fixed at compile time. This ensures that subclasses 
> can inherit
> protocol implementations without having to re-implement that code at each 
> level of
> inheritance.
> 
> Under this proposal, a new identifier keyword is fixed in use at the point of 
> protocol conformance
> to the static type of that construct. 
> 
> class A: MyProtocol
> The invariant StaticSelf identifier will always refer to A, unlike Self, 
> which is covarying and refers to
> the type of the actual instance. Since multiple inheritance for non-protocol 
> types is disallowed,
> this establishes this invariant type identifier with no possibility for 
> conflict.
> 
> Consider the following example, under the current system:
> 
> protocol StringCreatable {
> static func createWithString(s: String) -> Self
> }
> 
> extension NSURL: StringCreatable {
>  // cannot conform because NSURL is non-final
>  // error: method 'createWithString' in non-final class 'NSURL' must return 
> `Self` to conform to protocol 'A'
> }
> Introducing a static, invariant version of Self permits the desired 
> conformance:
> 
> protocol StringCreatable {
> static func createWithString(s: String) -> StaticSelf
> }
> 
> extension NSURL: StringCreatable {
>  // can now conform conform because NSURL is fixed and matches the static
>  // type of the conforming construct. Subclasses need not re-implement
>  // NOTE: the return type can be declared as StaticSelf *or* as NSURL
>  //   they are interchangeable
>  static func createWithString(s: String) -> StaticSelf { 
>  // ...
>  }
> }
> Additional Utility
> 
> The utility of StaticSelf is not limited to protocols. A secondary use 
> enables code to refer to the lexical context’s current type without 
> explicitly mentioning its name. This provides a useful shortcut when 
> referencing static type members with especially long names and when 
> re-purposing code between types.
> 
> class StructWithAVeryLongName {
> static func foo() -> String {
>   // ...
> }
> func bar() {
>   // ...
>   let s = StaticSelf.foo()
>   //
> }
> }
> Detailed Design
> 
> This proposal introduces StaticSelf, a new keyword that may be used in 
> protocols to refer to the invariant static type of a conforming 

Re: [swift-evolution] [Draft] Introducing StaticSelf, an Invariant Self

2016-05-14 Thread Vladimir.S via swift-evolution

Hmm.. very interesting..

@Matthew, is the code below looks like the same as you wanted to achieve 
with `->StaticSelf` ?


protocol Makable {
associatedtype MadeType
func make(value: Int) -> MadeType
}

class A {

}

class B: A {
func make(value: Int) -> B {
return B()
}
}

class C : B {
override func make(value: Int) -> B {
return C()
}
}


extension B : Makable {
typealias MadeType = B
}

func makeWithZero(creator t: T) -> T.MadeType {
return t.make(0)
}

var instance : B = C()

print(instance.make(0)) // main.C
print(makeWithZero(creator: instance))  // main.C



On 14.05.2016 8:55, Nicola Salmoria via swift-evolution wrote:

Matthew Johnson via swift-evolution  writes:


I agree it’s a bit tricky.  But that’s better than not possible at all.

 You just need a typealias and a same type constraint to make this work as
expected / desired:



protocol Makable {

typealias RootMakable = StaticSelf
static func make(value: Int) -> StaticSelf
}

func makeWithZero(x: Int) -> T {
return T.make(value: 0) // works now
 }


Now that we have a typealias we can refer to the binding of StaticSelf and

constrain it as necessary for whatever purpose we have in mind.  In some
cases that will be a same type constraint so that our code works properly
with class clusters.  I don’t have concrete examples of other use cases but
can imagine use cases constraining the typealias to a protocol, for example.

You can do that today:

protocol Makable {
associatedtype MadeType
static func make(value: Int) -> MadeType
}

func makeWithZero(x: Int) -> T {
return T.make(value: 0)
}

You can't currently constrain MadeType to be the same as the conforming
type, but, does it matter? What kind of extra guarantees would that give,
since you need to add the extra constraint anyway in generic code?

Nicola
___
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] [Draft] Introducing StaticSelf, an Invariant Self

2016-05-13 Thread Nicola Salmoria via swift-evolution
Matthew Johnson via swift-evolution  writes:

> I agree it’s a bit tricky.  But that’s better than not possible at all.
 You just need a typealias and a same type constraint to make this work as
expected / desired:
> 
> 
> protocol Makable {
> 
>   typealias RootMakable = StaticSelf
>   static func make(value: Int) -> StaticSelf
> }
>
> func makeWithZero(x: Int) -> T {
>   return T.make(value: 0) // works now
> }
> 
> 
> Now that we have a typealias we can refer to the binding of StaticSelf and
constrain it as necessary for whatever purpose we have in mind.  In some
cases that will be a same type constraint so that our code works properly
with class clusters.  I don’t have concrete examples of other use cases but
can imagine use cases constraining the typealias to a protocol, for example.

You can do that today:

protocol Makable {
associatedtype MadeType
static func make(value: Int) -> MadeType
}

func makeWithZero(x: Int) -> T {
return T.make(value: 0)
}

You can't currently constrain MadeType to be the same as the conforming
type, but, does it matter? What kind of extra guarantees would that give,
since you need to add the extra constraint anyway in generic code?

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


Re: [swift-evolution] [Draft] Introducing StaticSelf, an Invariant Self

2016-05-13 Thread Matthew Johnson via swift-evolution

> On May 13, 2016, at 3:12 PM, Joe Groff  wrote:
> 
>> 
>> On May 13, 2016, at 9:06 AM, Matthew Johnson  wrote:
>> 
>> 
>>> On May 13, 2016, at 10:55 AM, Joe Groff  wrote:
>>> 
>>> 
 On May 13, 2016, at 8:18 AM, Matthew Johnson  
 wrote:
 
 When I write a class Base with non-final methods that return instances of 
 Base I can choose whether to state the return type as Self (covariant) or 
 Base (invariant, under this proposal StaticSelf would also be an 
 alternative way to state this).  If I choose to specify Base as the return 
 type derived classes *may* override the method but are not required to.  
 Further, if they *do* override the method they are allowed to choose 
 whether their implementation returns Base or Derived.
>>> 
>>> `StaticSelf` requirements by themselves don't even save you from 
>>> covariance. If Base conforms to a protocol (with Self == Base), Derived 
>>> inherits that conformance and also conforms (with Self == Derived). If 
>>> `StaticSelf` always refers to the conforming type, then it must also be 
>>> bindable to Base and Derived, so a base class must still use a 
>>> covariant-returning method to satisfy the `StaticSelf` requirement.
>> 
>> We are specifying that `StaticSelf` refers to the type that explicitly 
>> declares conformance.  If a class inherits conformance it refers to the base 
>> class which explicitly declared the conformance it is inheriting.
> 
> That makes `StaticSelf` tricky to use in generic code. This would be invalid:
> 
> protocol Makable {
>   static func make(value: Int) -> StaticSelf
> }
> 
> func makeWithZero(x: Int) -> T {
>   return T.make(value: 0) // ERROR: T.StaticSelf may be a supertype of T 
> so isn't convertible to T
> }

I agree it’s a bit tricky.  But that’s better than not possible at all.  You 
just need a typealias and a same type constraint to make this work as expected 
/ desired:

protocol Makable {
typealias RootMakable = StaticSelf
static func make(value: Int) -> StaticSelf
}

func makeWithZero(x: Int) -> T {
return T.make(value: 0) // works now 
}

Now that we have a typealias we can refer to the binding of StaticSelf and 
constrain it as necessary for whatever purpose we have in mind.  In some cases 
that will be a same type constraint so that our code works properly with class 
clusters.  I don’t have concrete examples of other use cases but can imagine 
use cases constraining the typealias to a protocol, for example.

If we had control over inheritance of conformance at the point of conformance 
we probably wouldn’t be talking about StaticSelf.  But we don’t and this is a 
problem that has caused enough people trouble that it is worth solving.  
StaticSelf does that in a general way that is also as a shorthand in types 
themselves and has consistent semantics in both use cases.  

IIRC the design of point-of-conformance control over inheritance of conformance 
is pretty thorny.  I wouldn’t mind seeing that feature eventually but don’t 
have any confidence that it will come soon.  

> 
> `StaticSelf` in this model is effectively an associated type of the protocol, 
> with a `Self: StaticSelf` constraint (if that were supported).

If you add that the associated type is automatically bound with the initial 
conformance (and cannot be modified by subclass conformances) then yes, you can 
look at it this way.



> 
> -Joe

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


Re: [swift-evolution] [Draft] Introducing StaticSelf, an Invariant Self

2016-05-13 Thread Joe Groff via swift-evolution

> On May 13, 2016, at 9:06 AM, Matthew Johnson  wrote:
> 
> 
>> On May 13, 2016, at 10:55 AM, Joe Groff  wrote:
>> 
>> 
>>> On May 13, 2016, at 8:18 AM, Matthew Johnson  wrote:
>>> 
>>> When I write a class Base with non-final methods that return instances of 
>>> Base I can choose whether to state the return type as Self (covariant) or 
>>> Base (invariant, under this proposal StaticSelf would also be an 
>>> alternative way to state this).  If I choose to specify Base as the return 
>>> type derived classes *may* override the method but are not required to.  
>>> Further, if they *do* override the method they are allowed to choose 
>>> whether their implementation returns Base or Derived.
>> 
>> `StaticSelf` requirements by themselves don't even save you from covariance. 
>> If Base conforms to a protocol (with Self == Base), Derived inherits that 
>> conformance and also conforms (with Self == Derived). If `StaticSelf` always 
>> refers to the conforming type, then it must also be bindable to Base and 
>> Derived, so a base class must still use a covariant-returning method to 
>> satisfy the `StaticSelf` requirement.
> 
> We are specifying that `StaticSelf` refers to the type that explicitly 
> declares conformance.  If a class inherits conformance it refers to the base 
> class which explicitly declared the conformance it is inheriting.

That makes `StaticSelf` tricky to use in generic code. This would be invalid:

protocol Makable {
static func make(value: Int) -> StaticSelf
}

func makeWithZero(x: Int) -> T {
return T.make(value: 0) // ERROR: T.StaticSelf may be a supertype of T 
so isn't convertible to T
}

`StaticSelf` in this model is effectively an associated type of the protocol, 
with a `Self: StaticSelf` constraint (if that were supported).

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


Re: [swift-evolution] [Draft] Introducing StaticSelf, an Invariant Self

2016-05-13 Thread Matthew Johnson via swift-evolution

> On May 13, 2016, at 1:11 PM, Nicola Salmoria via swift-evolution 
>  wrote:
> 
> 
> 
> On Fri, May 13, 2016 at 12:55 PM, Vladimir.S  > wrote:
> > I'm not convinced by this example.
> 
> Probably my & Matthew's previous discussion in `[swift-evolution] [RFC] 
> #Self` topic will help you. I was trying there to find out (in primitive 
> examples) what Matthew is trying to achive with this `->StaticSelf` in 
> protocol.
> 
> In two words - he wants to achieve requirement 'return Self class or any of 
> base classes', as current `->Self` requires 'strictly return Self class'
> 
> I think I understand what the request is, but I'm not sure if it's a problem 
> worth solving, and if this would be the right solution.
>  
> Going back to the example, let's say you have the requested
> 
> protocol Fooable {
> func foo() -> StaticSelf
> }
> 
> class A: Fooable {
> func foo() -> A { return A() }
> }
> 
> class B: A {
> }
> 
> How would you use foo() in generic code?
> 
> func bar(_ x: T) -> X {
> return x.foo()
> }
> 
> What does bar() return? What do you put in place of X in its declaration?
> You can't use T, you can't use T.StaticSelf. So what's the purpose of having 
> a protocol if you can't use it in generic code?

This is a good question.  Thank you very much for providing a concrete example 
along with the question.

Let’s look at an example of what some of us have in mind:

protocol StringCreatable {
static func createWithString(s: String) -> StaticSelf
}

extension NSURL: StringCreatable {
static func createWithString(s: String) -> StaticSelf { 
// ...
}
}

func foo(s: String) -> Result {
return Result.createWithString(s: s)
}

Obviously this will not work properly because we are not guaranteed that 
`createWithString` returns Result (that is only possible if the return type is 
Self).  We would have to do the following:

protocol StringCreatable {
typealias ConformingType = StaticSelf
static func createWithString(s: String) -> StaticSelf
}

func foo(s: 
String) -> Result {
return Result.createWithString(s: s)
}

This requires same type constraints.  I believe that is coming as part of 
“completing generics”.  

However, it also raises a question: if the conformance afforded to subclasses 
can’t actually be used in a useful manner they probably shouldn’t have that 
conformance in the first place.  If the conformance isn’t inherited then we 
don’t need StaticSelf at all (we can just use Self and still conform the 
visible class of a class cluster).  This is the point Joe has been making all 
along.  Working through the example has helped me understand this point of view 
better.

I wonder if anyone has any other examples where subclass conformance would 
actually be useful.  If so, please share.  Those who are supporting this 
proposal: how do you envision using StaticSelf in your code?  What are some 
examples where you have had trouble due to the current limitations of the 
language?

-Matthew


> 
> 
> Nicola
> 
> ___
> 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] [Draft] Introducing StaticSelf, an Invariant Self

2016-05-13 Thread Joe Groff via swift-evolution

> On May 13, 2016, at 9:22 AM, Matthew Johnson  wrote:
> 
> 
> 
> Sent from my iPad
> 
>> On May 13, 2016, at 11:08 AM, Joe Groff  wrote:
>> 
>> 
>>> On May 13, 2016, at 9:06 AM, Matthew Johnson  wrote:
>>> 
>>> 
> On May 13, 2016, at 10:39 AM, Joe Groff  wrote:
> 
> 
> On May 13, 2016, at 8:18 AM, Matthew Johnson  
> wrote:
> 
> 
> 
> Sent from my iPad
> 
>> On May 12, 2016, at 9:21 PM, Joe Groff  wrote:
>> 
>> 
>>> On May 12, 2016, at 5:49 PM, Matthew Johnson via swift-evolution 
>>>  wrote:
>>> 
>>> The invariant StaticSelf identifier will always refer to A, unlike 
>>> Self, which is covarying and refers to
>>> the type of the actual instance. Since multiple inheritance for 
>>> non-protocol types is disallowed,
>>> this establishes this invariant type identifier with no possibility for 
>>> conflict.
>>> 
>>> Consider the following example, under the current system:
>>> 
>>> protocol StringCreatable 
>>> {
>>> 
>>> static func createWithString(s: String) -> Self
>>> 
>>> }
>>> 
>>> 
>>> extension NSURL: StringCreatable 
>>> {
>>> 
>>> // cannot conform because NSURL is non-final
>>> 
>>> 
>>> // error: method 'createWithString' in non-final class 'NSURL' must 
>>> return `Self` to conform to protocol 'A'
>>> 
>>> }
>>> 
>>> Introducing a static, invariant version of Self permits the desired 
>>> conformance:
>>> 
>>> protocol StringCreatable 
>>> {
>>> 
>>> static func createWithString(s: String) -> StaticSelf
>>> 
>>> }
>>> 
>>> 
>>> extension NSURL: StringCreatable 
>>> {
>>> 
>>> // can now conform conform because NSURL is fixed and matches the static
>>> 
>>> 
>>> // type of the conforming construct. Subclasses need not re-implement
>>> 
>>> 
>>> // NOTE: the return type can be declared as StaticSelf *or* as NSURL
>>> 
>>> 
>>> //   they are interchangeable
>>> 
>>> 
>>> static func createWithString(s: String) -> StaticSelf
>>> { 
>>> 
>>> // ...
>>> 
>>> }
>>> }
>> 
>> As I've noted before, I don't think this makes sense to encode in the 
>> protocol. `Self` is already effectively invariant within a protocol.
> 
> 'Self' is not invariant when used as a return type so I'm not sure what 
> you mean.
 
 That's a property of a conformance. Class conformances are inherited, so 
 they have to satisfy a protocol's requirements . Within the protocol 
 definition, or in a protocol extension, `Self` is a generic parameter 
 bound to a specific conforming type. When you conform a base class to a 
 type, that means `Self == Base` and `Self == Derived` must be possible, 
 but `Self` is never simultaneously `Base` and `Derived`.
 
>> If a protocol doesn't have the foresight to use StaticSelf, then you 
>> still have the same problems retroactively conforming class hierarchies 
>> to the protocol.
> 
> True, but in many use cases we are in control of the protocol.  This has 
> always been the case when I have personally encountered this problem.
 
 That will likely change once resilient Swift frameworks start to exist. 
 Changing `Self` to `StaticSelf` or back would also be a nonresilient 
 change, so if frameworks get this wrong, they wouldn't be able to fix it 
 without breaking ABI, which makes this even more problematic.
>>> 
>>> You can say this about many things.  It seems less problematic than having 
>>> no way to express this.  Frameworks would not be required to use it if the 
>>> authors have concerns about ABI.
>> 
>> In this particular case, making conformances non-inheritable, under the 
>> conformer's control, would avoid the issue of the framework having to 
>> anticipate its users' needs.
> 
> How would that work for class clusters?  I may have an instance of a subclass 
> but only know about the visible superclass.  When the visible superclass 
> conforms to a protocol I expect that the instance I have a reference to also 
> conforms, regardless of its dynamic type.  

In most cases, the subtype conversion should still kick in, so that we can 
convert ImplSubclass to VisibleSuperclass and invoke a generic with T == 
VisibleSuperclass instead of with T == ImplSubclass. There might be problems if 
the ImplSubclass appeared structurally in an invariant position, where implicit 
conversion is rare, but for situations where you want invariant protocol 
conformances, such as class clusters, it's rare to work to specific 
implementation classes directly, since the visible superclass is the primary 
API interface.

-Joe

Re: [swift-evolution] [Draft] Introducing StaticSelf, an Invariant Self

2016-05-13 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On May 13, 2016, at 11:08 AM, Joe Groff  wrote:
> 
> 
>> On May 13, 2016, at 9:06 AM, Matthew Johnson  wrote:
>> 
>> 
 On May 13, 2016, at 10:39 AM, Joe Groff  wrote:
 
 
 On May 13, 2016, at 8:18 AM, Matthew Johnson  
 wrote:
 
 
 
 Sent from my iPad
 
> On May 12, 2016, at 9:21 PM, Joe Groff  wrote:
> 
> 
>> On May 12, 2016, at 5:49 PM, Matthew Johnson via swift-evolution 
>>  wrote:
>> 
>> The invariant StaticSelf identifier will always refer to A, unlike Self, 
>> which is covarying and refers to
>> the type of the actual instance. Since multiple inheritance for 
>> non-protocol types is disallowed,
>> this establishes this invariant type identifier with no possibility for 
>> conflict.
>> 
>> Consider the following example, under the current system:
>> 
>> protocol StringCreatable 
>> {
>> 
>> static func createWithString(s: String) -> Self
>> 
>> }
>> 
>> 
>> extension NSURL: StringCreatable 
>> {
>> 
>> // cannot conform because NSURL is non-final
>> 
>> 
>> // error: method 'createWithString' in non-final class 'NSURL' must 
>> return `Self` to conform to protocol 'A'
>> 
>> }
>> 
>> Introducing a static, invariant version of Self permits the desired 
>> conformance:
>> 
>> protocol StringCreatable 
>> {
>> 
>> static func createWithString(s: String) -> StaticSelf
>> 
>> }
>> 
>> 
>> extension NSURL: StringCreatable 
>> {
>> 
>> // can now conform conform because NSURL is fixed and matches the static
>> 
>> 
>> // type of the conforming construct. Subclasses need not re-implement
>> 
>> 
>> // NOTE: the return type can be declared as StaticSelf *or* as NSURL
>> 
>> 
>> //   they are interchangeable
>> 
>> 
>> static func createWithString(s: String) -> StaticSelf
>> { 
>> 
>> // ...
>> 
>> }
>> }
> 
> As I've noted before, I don't think this makes sense to encode in the 
> protocol. `Self` is already effectively invariant within a protocol.
 
 'Self' is not invariant when used as a return type so I'm not sure what 
 you mean.
>>> 
>>> That's a property of a conformance. Class conformances are inherited, so 
>>> they have to satisfy a protocol's requirements . Within the protocol 
>>> definition, or in a protocol extension, `Self` is a generic parameter bound 
>>> to a specific conforming type. When you conform a base class to a type, 
>>> that means `Self == Base` and `Self == Derived` must be possible, but 
>>> `Self` is never simultaneously `Base` and `Derived`.
>>> 
> If a protocol doesn't have the foresight to use StaticSelf, then you 
> still have the same problems retroactively conforming class hierarchies 
> to the protocol.
 
 True, but in many use cases we are in control of the protocol.  This has 
 always been the case when I have personally encountered this problem.
>>> 
>>> That will likely change once resilient Swift frameworks start to exist. 
>>> Changing `Self` to `StaticSelf` or back would also be a nonresilient 
>>> change, so if frameworks get this wrong, they wouldn't be able to fix it 
>>> without breaking ABI, which makes this even more problematic.
>> 
>> You can say this about many things.  It seems less problematic than having 
>> no way to express this.  Frameworks would not be required to use it if the 
>> authors have concerns about ABI.
> 
> In this particular case, making conformances non-inheritable, under the 
> conformer's control, would avoid the issue of the framework having to 
> anticipate its users' needs.

How would that work for class clusters?  I may have an instance of a subclass 
but only know about the visible superclass.  When the visible superclass 
conforms to a protocol I expect that the instance I have a reference to also 
conforms, regardless of its dynamic type.  

> 
> -Joe

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


Re: [swift-evolution] [Draft] Introducing StaticSelf, an Invariant Self

2016-05-13 Thread Joe Groff via swift-evolution

> On May 13, 2016, at 9:06 AM, Matthew Johnson  wrote:
> 
> 
>> On May 13, 2016, at 10:39 AM, Joe Groff  wrote:
>> 
>>> 
>>> On May 13, 2016, at 8:18 AM, Matthew Johnson  wrote:
>>> 
>>> 
>>> 
>>> Sent from my iPad
>>> 
>>> On May 12, 2016, at 9:21 PM, Joe Groff  wrote:
>>> 
 
> On May 12, 2016, at 5:49 PM, Matthew Johnson via swift-evolution 
>  wrote:
> 
> The invariant StaticSelf identifier will always refer to A, unlike Self, 
> which is covarying and refers to
> the type of the actual instance. Since multiple inheritance for 
> non-protocol types is disallowed,
> this establishes this invariant type identifier with no possibility for 
> conflict.
> 
> Consider the following example, under the current system:
> 
> protocol StringCreatable 
> {
> 
> static func createWithString(s: String) -> Self
> 
> }
> 
> 
> extension NSURL: StringCreatable 
> {
> 
> // cannot conform because NSURL is non-final
> 
> 
> // error: method 'createWithString' in non-final class 'NSURL' must 
> return `Self` to conform to protocol 'A'
> 
> }
> 
> Introducing a static, invariant version of Self permits the desired 
> conformance:
> 
> protocol StringCreatable 
> {
> 
> static func createWithString(s: String) -> StaticSelf
> 
> }
> 
> 
> extension NSURL: StringCreatable 
> {
> 
> // can now conform conform because NSURL is fixed and matches the static
> 
> 
> // type of the conforming construct. Subclasses need not re-implement
> 
> 
> // NOTE: the return type can be declared as StaticSelf *or* as NSURL
> 
> 
> //   they are interchangeable
> 
> 
> static func createWithString(s: String) -> StaticSelf
> { 
> 
> // ...
> 
> }
> }
> 
> 
 
 As I've noted before, I don't think this makes sense to encode in the 
 protocol. `Self` is already effectively invariant within a protocol. 
>>> 
>>> 'Self' is not invariant when used as a return type so I'm not sure what you 
>>> mean.
>> 
>> That's a property of a conformance. Class conformances are inherited, so 
>> they have to satisfy a protocol's requirements . Within the protocol 
>> definition, or in a protocol extension, `Self` is a generic parameter bound 
>> to a specific conforming type. When you conform a base class to a type, that 
>> means `Self == Base` and `Self == Derived` must be possible, but `Self` is 
>> never simultaneously `Base` and `Derived`.
>> 
 If a protocol doesn't have the foresight to use StaticSelf, then you still 
 have the same problems retroactively conforming class hierarchies to the 
 protocol. 
>>> 
>>> True, but in many use cases we are in control of the protocol.  This has 
>>> always been the case when I have personally encountered this problem.
>> 
>> That will likely change once resilient Swift frameworks start to exist. 
>> Changing `Self` to `StaticSelf` or back would also be a nonresilient change, 
>> so if frameworks get this wrong, they wouldn't be able to fix it without 
>> breaking ABI, which makes this even more problematic.
> 
> You can say this about many things.  It seems less problematic than having no 
> way to express this.  Frameworks would not be required to use it if the 
> authors have concerns about ABI.

In this particular case, making conformances non-inheritable, under the 
conformer's control, would avoid the issue of the framework having to 
anticipate its users' needs.

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


Re: [swift-evolution] [Draft] Introducing StaticSelf, an Invariant Self

2016-05-13 Thread Matthew Johnson via swift-evolution

> On May 13, 2016, at 10:55 AM, Joe Groff  wrote:
> 
> 
>> On May 13, 2016, at 8:18 AM, Matthew Johnson  wrote:
>> 
>> When I write a class Base with non-final methods that return instances of 
>> Base I can choose whether to state the return type as Self (covariant) or 
>> Base (invariant, under this proposal StaticSelf would also be an alternative 
>> way to state this).  If I choose to specify Base as the return type derived 
>> classes *may* override the method but are not required to.  Further, if they 
>> *do* override the method they are allowed to choose whether their 
>> implementation returns Base or Derived.
> 
> `StaticSelf` requirements by themselves don't even save you from covariance. 
> If Base conforms to a protocol (with Self == Base), Derived inherits that 
> conformance and also conforms (with Self == Derived). If `StaticSelf` always 
> refers to the conforming type, then it must also be bindable to Base and 
> Derived, so a base class must still use a covariant-returning method to 
> satisfy the `StaticSelf` requirement.

We are specifying that `StaticSelf` refers to the type that explicitly declares 
conformance.  If a class inherits conformance it refers to the base class which 
explicitly declared the conformance it is inheriting.

> 
> -Joe

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


Re: [swift-evolution] [Draft] Introducing StaticSelf, an Invariant Self

2016-05-13 Thread Matthew Johnson via swift-evolution

> On May 13, 2016, at 10:39 AM, Joe Groff  wrote:
> 
>> 
>> On May 13, 2016, at 8:18 AM, Matthew Johnson  wrote:
>> 
>> 
>> 
>> Sent from my iPad
>> 
>> On May 12, 2016, at 9:21 PM, Joe Groff  wrote:
>> 
>>> 
 On May 12, 2016, at 5:49 PM, Matthew Johnson via swift-evolution 
  wrote:
 
 The invariant StaticSelf identifier will always refer to A, unlike Self, 
 which is covarying and refers to
 the type of the actual instance. Since multiple inheritance for 
 non-protocol types is disallowed,
 this establishes this invariant type identifier with no possibility for 
 conflict.
 
 Consider the following example, under the current system:
 
 protocol StringCreatable 
 {
 
 static func createWithString(s: String) -> Self
 
 }
 
 
 extension NSURL: StringCreatable 
 {
 
 // cannot conform because NSURL is non-final
 
 
 // error: method 'createWithString' in non-final class 'NSURL' must return 
 `Self` to conform to protocol 'A'
 
 }
 
 Introducing a static, invariant version of Self permits the desired 
 conformance:
 
 protocol StringCreatable 
 {
 
 static func createWithString(s: String) -> StaticSelf
 
 }
 
 
 extension NSURL: StringCreatable 
 {
 
 // can now conform conform because NSURL is fixed and matches the static
 
 
 // type of the conforming construct. Subclasses need not re-implement
 
 
 // NOTE: the return type can be declared as StaticSelf *or* as NSURL
 
 
 //   they are interchangeable
 
 
 static func createWithString(s: String) -> StaticSelf
 { 
 
 // ...
 
 }
 }
 
 
>>> 
>>> As I've noted before, I don't think this makes sense to encode in the 
>>> protocol. `Self` is already effectively invariant within a protocol. 
>> 
>> 'Self' is not invariant when used as a return type so I'm not sure what you 
>> mean.
> 
> That's a property of a conformance. Class conformances are inherited, so they 
> have to satisfy a protocol's requirements . Within the protocol definition, 
> or in a protocol extension, `Self` is a generic parameter bound to a specific 
> conforming type. When you conform a base class to a type, that means `Self == 
> Base` and `Self == Derived` must be possible, but `Self` is never 
> simultaneously `Base` and `Derived`.
> 
>>> If a protocol doesn't have the foresight to use StaticSelf, then you still 
>>> have the same problems retroactively conforming class hierarchies to the 
>>> protocol. 
>> 
>> True, but in many use cases we are in control of the protocol.  This has 
>> always been the case when I have personally encountered this problem.
> 
> That will likely change once resilient Swift frameworks start to exist. 
> Changing `Self` to `StaticSelf` or back would also be a nonresilient change, 
> so if frameworks get this wrong, they wouldn't be able to fix it without 
> breaking ABI, which makes this even more problematic.

You can say this about many things.  It seems less problematic than having no 
way to express this.  Frameworks would not be required to use it if the authors 
have concerns about ABI.

> 
> -Joe

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


Re: [swift-evolution] [Draft] Introducing StaticSelf, an Invariant Self

2016-05-13 Thread Joe Groff via swift-evolution

> On May 13, 2016, at 8:18 AM, Matthew Johnson  wrote:
> 
> 
> 
> Sent from my iPad
> 
> On May 12, 2016, at 9:21 PM, Joe Groff  wrote:
> 
>> 
>>> On May 12, 2016, at 5:49 PM, Matthew Johnson via swift-evolution 
>>>  wrote:
>>> 
>>> The invariant StaticSelf identifier will always refer to A, unlike Self, 
>>> which is covarying and refers to
>>> the type of the actual instance. Since multiple inheritance for 
>>> non-protocol types is disallowed,
>>> this establishes this invariant type identifier with no possibility for 
>>> conflict.
>>> 
>>> Consider the following example, under the current system:
>>> 
>>> protocol StringCreatable 
>>> {
>>> 
>>> static func createWithString(s: String) -> Self
>>> 
>>> }
>>> 
>>> 
>>> extension NSURL: StringCreatable 
>>> {
>>> 
>>> // cannot conform because NSURL is non-final
>>> 
>>> 
>>> // error: method 'createWithString' in non-final class 'NSURL' must return 
>>> `Self` to conform to protocol 'A'
>>> 
>>> }
>>> 
>>> Introducing a static, invariant version of Self permits the desired 
>>> conformance:
>>> 
>>> protocol StringCreatable 
>>> {
>>> 
>>> static func createWithString(s: String) -> StaticSelf
>>> 
>>> }
>>> 
>>> 
>>> extension NSURL: StringCreatable 
>>> {
>>> 
>>> // can now conform conform because NSURL is fixed and matches the static
>>> 
>>> 
>>> // type of the conforming construct. Subclasses need not re-implement
>>> 
>>> 
>>> // NOTE: the return type can be declared as StaticSelf *or* as NSURL
>>> 
>>> 
>>> //   they are interchangeable
>>> 
>>> 
>>> static func createWithString(s: String) -> StaticSelf
>>> { 
>>> 
>>> // ...
>>> 
>>> }
>>> }
>>> 
>>> 
>> 
>> As I've noted before, I don't think this makes sense to encode in the 
>> protocol. `Self` is already effectively invariant within a protocol. 
> 
> 'Self' is not invariant when used as a return type so I'm not sure what you 
> mean.

That's a property of a conformance. Class conformances are inherited, so they 
have to satisfy a protocol's requirements . Within the protocol definition, or 
in a protocol extension, `Self` is a generic parameter bound to a specific 
conforming type. When you conform a base class to a type, that means `Self == 
Base` and `Self == Derived` must be possible, but `Self` is never 
simultaneously `Base` and `Derived`.

>> If a protocol doesn't have the foresight to use StaticSelf, then you still 
>> have the same problems retroactively conforming class hierarchies to the 
>> protocol. 
> 
> True, but in many use cases we are in control of the protocol.  This has 
> always been the case when I have personally encountered this problem.

That will likely change once resilient Swift frameworks start to exist. 
Changing `Self` to `StaticSelf` or back would also be a nonresilient change, so 
if frameworks get this wrong, they wouldn't be able to fix it without breaking 
ABI, which makes this even more problematic.

-Joe

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


Re: [swift-evolution] [Draft] Introducing StaticSelf, an Invariant Self

2016-05-13 Thread Matthew Johnson via swift-evolution

> On May 13, 2016, at 1:45 AM, Patrick Smith via swift-evolution 
>  wrote:
> 
> Could protocol Self change to just the first behaviour for classes?
> 
> If a conformance absolutely needs to have a method returning ‘only me but not 
> my subclasses’, then it sets that conforming method to be final.

It does not say the method returns “only me but not my subclasses”.  It just 
says “subclasses are not *required* to return an instance of their own type, 
the original conforming type is sufficient to meet the requirement”.

This is quite a bit different from a ‘final’ requirement.  Subclasses are 
allowed to override the implementation if desired.  If they do choose to 
override the implementation they have more flexibility in *how* to implement it 
and what signature to expose.  This is exactly the same as a method in Base 
that is declared as returning Base rather than returning Self. 


> 
> 
>> On 13 May 2016, at 4:38 PM, Vladimir.S  wrote:
>> 
>> The proposed StaticSelf when used as `->StaticSelf` in protocol means 
>> ‘myself or my some *base* class’. I.e. if this requirement was implemented 
>> in one of base classes, any subclass automatically conforms to the protocol 
>> as it has `->(myself or some base class)` in his hierarchy.
>> 
>> This is the difference with `->Self` in protocol which requires 'myself'.
>> 
>> On 13.05.2016 7:21, Patrick Smith via swift-evolution wrote:
>>> I didn’t really understand some of the lead in discussion examples
>>> regarding protocols A and B each being interwoven, but I would prefer to
>>> see StaticSelf only used for concrete types, and protocols only to use
>>> Self. If Self has problems with non-final classes, then maybe how it
>>> works in protocols could change. A class could interpret a protocol’s
>>> ‘Self’ as ‘myself or my subclasses’?
>>> 
>>> Maybe instead of introducing StaticSelf it could be renamed simply Self,
>>> and ‘Self’ as used in protocols could change to something else?
>>> ‘Instance’ perhaps?
>>> 
 On 13 May 2016, at 12:21 PM, Joe Groff via swift-evolution
  wrote:
 
 
> On May 12, 2016, at 5:49 PM, Matthew Johnson via swift-evolution
>  wrote:
> 
> The invariant StaticSelf identifier will always refer to A, unlike
> Self, which is covarying and refers to the type of the actual
> instance. Since multiple inheritance for non-protocol types is
> disallowed, this establishes this invariant type identifier with no
> possibility for conflict.
> 
> Consider the following example, under the current system:
> 
> protocol StringCreatable {
> 
> static func createWithString(s: String) -> Self
> 
> }
> 
> 
> extension NSURL: StringCreatable {
> 
> // cannot conform because NSURL is non-final
> 
> 
> // error: method 'createWithString' in non-final class 'NSURL' must
> return `Self` to conform to protocol 'A'
> 
> }
> 
> Introducing a static, invariant version of Self permits the desired
> conformance:
> 
> protocol StringCreatable {
> 
> static func createWithString(s: String) -> StaticSelf
> 
> }
> 
> 
> extension NSURL: StringCreatable {
> 
> // can now conform conform because NSURL is fixed and matches the
> static
> 
> 
> // type of the conforming construct. Subclasses need not
> re-implement
> 
> 
> // NOTE: the return type can be declared as StaticSelf *or* as
> NSURL
> 
> 
> //   they are interchangeable
> 
> 
> static func createWithString(s: String) -> StaticSelf {
> 
> // ...
> 
> } }
> 
> 
 
 As I've noted before, I don't think this makes sense to encode in the
 protocol. `Self` is already effectively invariant within a protocol.
 If a protocol doesn't have the foresight to use StaticSelf, then you
 still have the same problems retroactively conforming class
 hierarchies to the protocol. Whether a conformance is inherited or not
 feels more natural as a property of a conformance, not something that
 can be legislated a priori by a protocol definition.
 
 Something like StaticSelf might still be useful as shorthand within a
 class definition with a long-winded name, though `StaticSelf` feels
 kind of long as a shortcut to me.
 
 -Joe ___ 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
> 

Re: [swift-evolution] [Draft] Introducing StaticSelf, an Invariant Self

2016-05-13 Thread Matthew Johnson via swift-evolution

> On May 13, 2016, at 1:26 AM, David Hart  wrote:
> 
> Totally agree. It feels weird to have protocols decide on how "Self" 
> conformance a are inherited. It should a decision for the conforming type.

Do you have any suggestions on how we allow the conforming type to make that 
decision?  Last time we had that discussion it didn’t produce clear answer.  It 
turns out there is quite a bit of complexity involved in doing this.

> 
>> On 13 May 2016, at 04:21, Joe Groff via swift-evolution 
>>  wrote:
>> 
>> 
>>> On May 12, 2016, at 5:49 PM, Matthew Johnson via swift-evolution 
>>>  wrote:
>>> 
>>> The invariant StaticSelf identifier will always refer to A, unlike Self, 
>>> which is covarying and refers to
>>> the type of the actual instance. Since multiple inheritance for 
>>> non-protocol types is disallowed,
>>> this establishes this invariant type identifier with no possibility for 
>>> conflict.
>>> 
>>> Consider the following example, under the current system:
>>> 
>>> protocol StringCreatable 
>>> {
>>> 
>>> static func createWithString(s: String) -> Self
>>> 
>>> }
>>> 
>>> 
>>> extension NSURL: StringCreatable 
>>> {
>>> 
>>> // cannot conform because NSURL is non-final
>>> 
>>> 
>>> // error: method 'createWithString' in non-final class 'NSURL' must return 
>>> `Self` to conform to protocol 'A'
>>> 
>>> }
>>> 
>>> Introducing a static, invariant version of Self permits the desired 
>>> conformance:
>>> 
>>> protocol StringCreatable 
>>> {
>>> 
>>> static func createWithString(s: String) -> StaticSelf
>>> 
>>> }
>>> 
>>> 
>>> extension NSURL: StringCreatable 
>>> {
>>> 
>>> // can now conform conform because NSURL is fixed and matches the static
>>> 
>>> 
>>> // type of the conforming construct. Subclasses need not re-implement
>>> 
>>> 
>>> // NOTE: the return type can be declared as StaticSelf *or* as NSURL
>>> 
>>> 
>>> //   they are interchangeable
>>> 
>>> 
>>> static func createWithString(s: String) -> StaticSelf
>>> { 
>>> 
>>> // ...
>>> 
>>> }
>>> }
>> 
>> As I've noted before, I don't think this makes sense to encode in the 
>> protocol. `Self` is already effectively invariant within a protocol. If a 
>> protocol doesn't have the foresight to use StaticSelf, then you still have 
>> the same problems retroactively conforming class hierarchies to the 
>> protocol. Whether a conformance is inherited or not feels more natural as a 
>> property of a conformance, not something that can be legislated a priori by 
>> a protocol definition.
>> 
>> Something like StaticSelf might still be useful as shorthand within a class 
>> definition with a long-winded name, though `StaticSelf` feels kind of long 
>> as a shortcut to me.
>> 
>> -Joe
>> ___
>> 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] [Draft] Introducing StaticSelf, an Invariant Self

2016-05-13 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On May 12, 2016, at 9:21 PM, Joe Groff  wrote:
> 
> 
>> On May 12, 2016, at 5:49 PM, Matthew Johnson via swift-evolution 
>>  wrote:
>> 
>> The invariant StaticSelf identifier will always refer to A, unlike Self, 
>> which is covarying and refers to
>> the type of the actual instance. Since multiple inheritance for non-protocol 
>> types is disallowed,
>> this establishes this invariant type identifier with no possibility for 
>> conflict.
>> 
>> Consider the following example, under the current system:
>> 
>> protocol StringCreatable 
>> {
>> 
>> static func createWithString(s: String) -> Self
>> 
>> }
>> 
>> 
>> extension NSURL: StringCreatable 
>> {
>> 
>> // cannot conform because NSURL is non-final
>> 
>> 
>> // error: method 'createWithString' in non-final class 'NSURL' must return 
>> `Self` to conform to protocol 'A'
>> 
>> }
>> 
>> Introducing a static, invariant version of Self permits the desired 
>> conformance:
>> 
>> protocol StringCreatable 
>> {
>> 
>> static func createWithString(s: String) -> StaticSelf
>> 
>> }
>> 
>> 
>> extension NSURL: StringCreatable 
>> {
>> 
>> // can now conform conform because NSURL is fixed and matches the static
>> 
>> 
>> // type of the conforming construct. Subclasses need not re-implement
>> 
>> 
>> // NOTE: the return type can be declared as StaticSelf *or* as NSURL
>> 
>> 
>> //   they are interchangeable
>> 
>> 
>> static func createWithString(s: String) -> StaticSelf
>> { 
>> 
>> // ...
>> 
>> }
>> }
> 
> As I've noted before, I don't think this makes sense to encode in the 
> protocol. `Self` is already effectively invariant within a protocol.
> 
> As I've noted before, I don't think this makes sense to encode in the 
> protocol. `Self` is already effectively invariant within a protocol.

'Self' is not invariant when used as a return type so I'm not sure what you 
mean.

> If a protocol doesn't have the foresight to use StaticSelf, then you still 
> have the same problems retroactively conforming class hierarchies to the 
> protocol.

True, but in many use cases we are in control of the protocol.  This has always 
been the case when I have personally encountered this problem.

> Whether a conformance is inherited or not feels more natural as a property of 
> a conformance, not something that can be legislated a priori by a protocol 
> definition.

This proposal does not allow protocols to legislate whether conformance is 
inherited or not.  It just allows the protocol to specify more precisely how 
requirements are inherited.   

When I write a class Base with non-final methods that return instances of Base 
I can choose whether to state the return type as Self (covariant) or Base 
(invariant, under this proposal StaticSelf would also be an alternative way to 
state this).  If I choose to specify Base as the return type derived classes 
*may* override the method but are not required to.  Further, if they *do* 
override the method they are allowed to choose whether their implementation 
returns Base or Derived.

I believe protocols should have the same flexibility.  If superclasses can 
control the variance of the return types of their inherited methods why 
shouldn't protocols be able to do so as well?  The weaker requirement can be 
very useful in some cases.

I think the case for StaticSelf is:

1. It is useful as a general substitute for the name of the containing type.
2. It solves real world use cases of providing protocol conformance.
3. It is a small change (on the surface, I can't speak to implementation) and 
may have a chance at making it into Swift 3.
4. The previous discussion about controlling conformance at the usage site 
didn't really seem to reach any conclusions.  My impression is that this is a 
feature that is difficult to design well and probably isn't going to be a 
priority, at least for a while.
5. StaticSelf is perfectly compatible with such a feature if it is introduced 
in the future.  

> 
> Something like StaticSelf might still be useful as shorthand within a class 
> definition with a long-winded name, though `StaticSelf` feels kind of long as 
> a shortcut to me.

That's a fair criticism for that use case.  Chris also mentioned that.  'Type' 
is the best shorter option we came up with.  We didn't go that route in the 
proposal because feels like it could be more confusing for those first learning 
it.  That said, we are willing to go with whatever the community decides on.  

If you like one of the alternatives better or have any new ideas please let us 
know...

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


Re: [swift-evolution] [Draft] Introducing StaticSelf, an Invariant Self

2016-05-13 Thread Vladimir.S via swift-evolution
After all these discussions, and after I found out *for myself* what does 
the proposed `->StaticSelf` in protocol mean, I'm giving my strong +1 to 
this proposal. This will be a good and useful in some cases language 
feature, that will add flexibility to Swift.


Also it will help to make the code clean and reduce copy-paste errors or 
requirements to re-type concrete type name inside its declaration.
It's so naturally to say 'this concrete type name' i.e. `StaticSelf` 
*inside* the type declaration instead of having its name everywhere. 
Especially, if name of the declaring type has common elements with another 
class like MyVeryGoodClass.f() and MyVeryBadClass.f() so I need to 
carefully read name of which class used.


But the question regarding the name of StaticSelf is still here...
I feel like something that will be resolved at compile-time should have `#` 
before its name.. Probably the best name for me is #BaseType (or #TypeBase, 
or #This #BaseThis #ThisBase)... as having StaticSelf, we IMO should have 
DynamicSelf instead of current `Self`.. Even probably the initially 
proposed #Self is better for me.

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


Re: [swift-evolution] [Draft] Introducing StaticSelf, an Invariant Self

2016-05-13 Thread Thorsten Seitz via swift-evolution

Am 13. Mai 2016 um 09:36 schrieb "Vladimir.S via swift-evolution" 
:


Why did you decide to drop the `#` ? As `StaticSelf` will be resolved on
compilation time like #file etc ? I feel like this is inconsistent solution.


# is not needed just like it is not needed for generic type parameters which 
are also resolved at compilation time. 
#file etc. insert information about artefacts outside of the language (i.e. the 
name of the file wherein the code resides) which is very different.


-Thorsten






Also, do you expect this will work:

protocol A {
func g()->StaticSelf
}

class B: A {
func g()->StaticSelf {return B()}
}

class C: B {
//func f(s: C) {}
}

func x(a: A ){
var xx : A = a.g() // ?
print(xx)
}

func z(t: T) {
let u = t.g() // ?
print(u)
}

let c = C()
z(c)
x(c)


On 13.05.2016 3:49, Matthew Johnson via swift-evolution wrote:

Erica Sadun and I have written a proposal are following up the recent
discussion thread "[RFC] #Self” with a proposal to introduce StaticSelf, an
invariant Self.


The recent discussion can be found
here: http://thread.gmane.org/gmane.comp.lang.swift.evolution/16565



The proposal can be found
here: 
https://github.com/anandabits/swift-evolution/blob/static-self/proposals/-static-self.md



We look forward to continuing the discussion. We plan to submit a PR in
the near future after incorporating your final feedback.


Thanks,
Matthew




Introducing StaticSelf, an Invariant Self


* Proposal: TBD
* Authors: Matthew Johnson , Erica Sadun


* Status: TBD
* Review manager: TBD




Introduction


This proposal introduces a new keyword that provides consistent invariant
type semantics in all contexts.


/The Swift-evolution thread about this topic can be found here: [RFC] #Self
/





Motivation


The distinction between covariant and non-covariant type references come
into play when
conforming non-final classes to protocols. Fixing a protocol requirement to
a covarying type
means that a method returning |Self| must be overriden by all subclasses in
order to return
the correct, matching type.


This proposal builds on the covariant construct |Self| accepted in SE–0068


to introduce an invariant type identifier. It enables protocol declarations
to consistently
refer to a type that is fixed at compile time. This ensures that subclasses
can inherit
protocol implementations without having to re-implement that code at each
level of
inheritance.


Under this proposal, a new identifier keyword is fixed in use /at the point
of protocol conformance/
to the static type of that construct.


|class A: MyProtocol|


The invariant |StaticSelf| identifier will always refer to |A|,
unlike |Self|, which is covarying and refers to
the type of the actual instance. Since multiple inheritance for
non-protocol types is disallowed,
this establishes this invariant type identifier with no possibility for
conflict.


Consider the following example, under the current system:


|protocol StringCreatable { static func createWithString(s: String) -> Self
} extension NSURL: StringCreatable { // cannot conform because NSURL is
non-final // error: method 'createWithString' in non-final class 'NSURL'
must return `Self` to conform to protocol 'A' }|


Introducing a static, invariant version of |Self| permits the desired
conformance:


|protocol StringCreatable { static func createWithString(s: String) ->
StaticSelf } extension NSURL: StringCreatable { // can now conform conform
because NSURL is fixed and matches the static // type of the conforming
construct. Subclasses need not re-implement // NOTE: the return type can be
declared as StaticSelf *or* as NSURL // they are interchangeable static
func createWithString(s: String) -> StaticSelf { // ... } }|




Additional Utility


The utility of |StaticSelf| is not limited to protocols. A secondary use
enables code to refer to the lexical context’s current type without
explicitly mentioning its name. This provides a useful shortcut when
referencing static type members with especially long names and when
re-purposing code between types.


|class StructWithAVeryLongName { static func foo() -> String { // ... } func
bar() { // ... let s = StaticSelf.foo() // } }|




Detailed Design


This proposal introduces |StaticSelf|, a new keyword that may be used in
protocols to refer to the invariant static type of a conforming
construct. |StaticSelf| may also be used in the lexical context of any type
declaration. In such use, the keyword is identical to spelling out the full
name of that type.




Impact on existing code


Being additive, there should be no impact on existing code.




Alternatives considered


The keyword is not fixed at this time. Alternatives that have been
discussed include |StaticType|, |InvariantSelf|, 

Re: [swift-evolution] [Draft] Introducing StaticSelf, an Invariant Self

2016-05-13 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On May 13, 2016, at 8:37 AM, Thorsten Seitz via swift-evolution 
>  wrote:
> 
> Comments inline.
> 
>> Am 13. Mai 2016 um 09:31 schrieb "Vladimir.S via swift-evolution" 
>> :
>> 
>> I don't feel that InvariantSelf reflects the fact that class conformed to 
>> protocol with `f()->InvariantSelf` requirement will actually return
>> 'self or some base class'. Especially when this `InvariantSelf` means 
>> `exactly this concrete static type name` inside type declaration.
>> 
>> Probably the better name is BaseType (BaseSelf, ThisType.. #Type ?)
>> 
>> But actually I don't fully understand how this would work in generic 
>> functions:
>> 
>> protocol A {
>> func g()->StaticSelf
>> }
>> 
>> class B: A {
>> func g()->StaticSelf {return B()}
>> }
>> 
>> class C: B {
>> }
>> 
>> 
>> func x(a: A ){
>> var xx : A = a.g() // will this work? as g returns *some in hierarchy*
>> print(xx)
>> }
> 
> 
> StaticSelf within the protocol should just be the protocol, i.e. here A
> 
> Only for non-protocol types conforming to the protocol StaticSelf becomes 
> equal to the first type where the respective method gets implemented (if we 
> should get abstract classes some day this would mean that for an abstract 
> class conforming to the protocol but not implementing the method a, 
> StaticSelf would still be A).
> 

Yes, it is exactly as if you had copy and pasted the signature from the 
protocol declaration into the conforming type.

>> 
>> func z(t: T) {
>> let u = t.g() // will this work?
>> print(u)
>> }
> 
> 
> This will work as well with static type of `u` being A.
> 
>> 
>> let c = C()
>> z(c)
> 
> 
> This is of course correct because C conforms to A. The static type of `u` 
> within `z` is A (see comment above). This is independent from the dynamic 
> type of the parameter `t` (which has nothing to do with StaticSelf).
> 
> 
>> x(c)
> 
> 
> Again `c` conforms to A, so this is correct.
> 
> -Thorsten
> 
> 
> 
>> 
>> 
>> 
>> 
>> 
>>> On 13.05.2016 4:59, Xiaodi Wu via swift-evolution wrote:
>>> I like the way the motivation for this feature has been explained here. Now
>>> that the reasoning behind it is evident, I have to say I'm leaning towards
>>> the "InvariantSelf" name--after all, you describe this feature in the title
>>> as "an invariant self."
>>> 
>>> 
>>> On Thu, May 12, 2016 at 7:49 PM, Matthew Johnson via swift-evolution
>>> > wrote:
>>> 
>>> Erica Sadun and I have written a proposal are following up the recent
>>> discussion thread "[RFC] #Self” with a proposal to introduce
>>> StaticSelf, an invariant Self.
>>> 
>>> The recent discussion can be found
>>> here: http://thread.gmane.org/gmane.comp.lang.swift.evolution/16565
>>> 
>>> The proposal can be found
>>> here: 
>>> https://github.com/anandabits/swift-evolution/blob/static-self/proposals/-static-self.md
>>> 
>>> We look forward to continuing the discussion. We plan to submit a PR
>>> in the near future after incorporating your final feedback.
>>> 
>>> Thanks,
>>> Matthew
>>> 
>>> 
>>> Introducing StaticSelf, an Invariant Self
>>> 
>>> * Proposal: TBD
>>> * Authors: Matthew Johnson , Erica
>>> Sadun 
>>> * Status: TBD
>>> * Review manager: TBD
>>> 
>>> 
>>> Introduction
>>> 
>>> This proposal introduces a new keyword that provides consistent
>>> invariant type semantics in all contexts.
>>> 
>>> /The Swift-evolution thread about this topic can be found here: [RFC]
>>> #Self /
>>> 
>>> 
>>> Motivation
>>> 
>>> The distinction between covariant and non-covariant type references
>>> come into play when
>>> conforming non-final classes to protocols. Fixing a protocol
>>> requirement to a covarying type
>>> means that a method returning |Self| must be overriden by all
>>> subclasses in order to return
>>> the correct, matching type.
>>> 
>>> This proposal builds on the covariant construct |Self| accepted
>>> in SE–0068
>>> 
>>> to introduce an invariant type identifier. It enables protocol
>>> declarations to consistently
>>> refer to a type that is fixed at compile time. This ensures that
>>> subclasses can inherit
>>> protocol implementations without having to re-implement that code at
>>> each level of
>>> inheritance.
>>> 
>>> Under this proposal, a new identifier keyword is fixed in use /at the
>>> point of protocol conformance/
>>> to the static type of that construct.
>>> 
>>> |class A: MyProtocol|
>>> 
>>> The invariant |StaticSelf| identifier will always refer to |A|,
>>> unlike |Self|, which is covarying and refers to
>>> the type of the actual instance. Since multiple inheritance for
>>> non-protocol types is disallowed,
>>> this establishes this invariant type identifier with no possibility for
>>> 

Re: [swift-evolution] [Draft] Introducing StaticSelf, an Invariant Self

2016-05-13 Thread Thorsten Seitz via swift-evolution

Comments inline.


Am 13. Mai 2016 um 09:31 schrieb "Vladimir.S via swift-evolution" 
:


I don't feel that InvariantSelf reflects the fact that class conformed to
protocol with `f()->InvariantSelf` requirement will actually return
'self or some base class'. Especially when this `InvariantSelf` means
`exactly this concrete static type name` inside type declaration.

Probably the better name is BaseType (BaseSelf, ThisType.. #Type ?)

But actually I don't fully understand how this would work in generic functions:

protocol A {
func g()->StaticSelf
}

class B: A {
func g()->StaticSelf {return B()}
}

class C: B {
}


func x(a: A ){
var xx : A = a.g() // will this work? as g returns *some in hierarchy*
print(xx)
}


StaticSelf within the protocol should just be the protocol, i.e. here A


Only for non-protocol types conforming to the protocol StaticSelf becomes equal 
to the first type where the respective method gets implemented (if we should 
get abstract classes some day this would mean that for an abstract class 
conforming to the protocol but not implementing the method a, StaticSelf would 
still be A).




func z(t: T) {
let u = t.g() // will this work?
print(u)
}


This will work as well with static type of `u` being A.



let c = C()
z(c)


This is of course correct because C conforms to A. The static type of `u` 
within `z` is A (see comment above). This is independent from the dynamic type 
of the parameter `t` (which has nothing to do with StaticSelf).




x(c)


Again `c` conforms to A, so this is correct.


-Thorsten











On 13.05.2016 4:59, Xiaodi Wu via swift-evolution wrote:

I like the way the motivation for this feature has been explained here. Now
that the reasoning behind it is evident, I have to say I'm leaning towards
the "InvariantSelf" name--after all, you describe this feature in the title
as "an invariant self."




On Thu, May 12, 2016 at 7:49 PM, Matthew Johnson via swift-evolution
> wrote:


Erica Sadun and I have written a proposal are following up the recent
discussion thread "[RFC] #Self” with a proposal to introduce
StaticSelf, an invariant Self.


The recent discussion can be found
here: http://thread.gmane.org/gmane.comp.lang.swift.evolution/16565



The proposal can be found
here: 
https://github.com/anandabits/swift-evolution/blob/static-self/proposals/-static-self.md



We look forward to continuing the discussion. We plan to submit a PR
in the near future after incorporating your final feedback.


Thanks,
Matthew




Introducing StaticSelf, an Invariant Self


* Proposal: TBD
* Authors: Matthew Johnson , Erica
Sadun 

* Status: TBD
* Review manager: TBD




Introduction


This proposal introduces a new keyword that provides consistent
invariant type semantics in all contexts.


/The Swift-evolution thread about this topic can be found here: [RFC]
#Self /





Motivation


The distinction between covariant and non-covariant type references
come into play when
conforming non-final classes to protocols. Fixing a protocol
requirement to a covarying type
means that a method returning |Self| must be overriden by all
subclasses in order to return
the correct, matching type.


This proposal builds on the covariant construct |Self| accepted
in SE–0068


to introduce an invariant type identifier. It enables protocol
declarations to consistently
refer to a type that is fixed at compile time. This ensures that
subclasses can inherit
protocol implementations without having to re-implement that code at
each level of
inheritance.


Under this proposal, a new identifier keyword is fixed in use /at the
point of protocol conformance/
to the static type of that construct.


|class A: MyProtocol|


The invariant |StaticSelf| identifier will always refer to |A|,
unlike |Self|, which is covarying and refers to
the type of the actual instance. Since multiple inheritance for
non-protocol types is disallowed,
this establishes this invariant type identifier with no possibility for
conflict.


Consider the following example, under the current system:


|protocol StringCreatable { static func createWithString(s: String) ->
Self } extension NSURL: StringCreatable { // cannot conform because
NSURL is non-final // error: method 'createWithString' in non-final
class 'NSURL' must return `Self` to conform to protocol 'A' }|


Introducing a static, invariant version of |Self| permits the desired
conformance:


|protocol StringCreatable { static func createWithString(s: String) ->
StaticSelf } extension NSURL: StringCreatable { // can now conform
conform because NSURL is fixed and matches the static // type of the
conforming construct. Subclasses need not re-implement // NOTE: the
return type can be 

Re: [swift-evolution] [Draft] Introducing StaticSelf, an Invariant Self

2016-05-13 Thread LM via swift-evolution


> On May 13, 2016, at 1:26 PM, Vladimir.S  wrote:
> 
> I don't understand.
> Right now we are allowed to have Optional(Self) :
> 
> protocol A {
>  func g()->Self?
> }
> 
> class B: A {
>  func g()->Self? {return self}
> }
> 
> print(B().g()) //Optional(main.B)
> 
> How do you want to divide your `->Self?` and this currently possible 
> `->Self?` ?
> 
> 
> But I do like the idea to separate meaning of `Self` in protocol with some 
> marker.. What about `->?Self` and `->!Self` - no confusing with Optional<>

My idea was to keep the markers at the end, rather than as a prefix (Lexer will 
thank you for it), such that in code completion they would be together, but 
your idea has some appeal.
Especially if the argument is made that the IDE should be smart enough to 
'cleanup' the list meaningfully, which I would expect coming from a decade of 
java as I do (at the risk of sounding critical, I am still rather put-off by 
the crude state of text editing in the obj-c/swift world). Although in 
fairness, mike & team have done marvels these last couple years.


> 
>> On 13.05.2016 14:21, LM via swift-evolution wrote:
>> 
>> The other advantage of Self! over StaticSelf is that in code completion,
>> Self, Self? Self! Will come together, giving people a quick tool to
>> discover/remind themselves of the semantic difference right at the point of
>> use.
>> 
>> It might also address Joe's comment about StaticSelf not being much of a
>> shortcut.
>> 
>> 
>> On May 13, 2016, at 1:15 PM, LM > > wrote:
>> 
>>> Considering the precedent of using ! and ? in swift, could it be that:
>>> 
>>> Self!  would designate what is known for sure, the invariant compile time
>>> type of self
>>> 
>>> Self? Would designate the yet unknown (*optional* if you will) covariant
>>> type of self
>>> 
>>> 
>>> Regards
>>> LM
>>> (From mobile)
>>> 
>>> On May 13, 2016, at 3:59 AM, Xiaodi Wu via swift-evolution
>>> > wrote:
>>> 
 I like the way the motivation for this feature has been explained here.
 Now that the reasoning behind it is evident, I have to say I'm leaning
 towards the "InvariantSelf" name--after all, you describe this feature
 in the title as "an invariant self."
 
 
 On Thu, May 12, 2016 at 7:49 PM, Matthew Johnson via swift-evolution
 > wrote:
 
Erica Sadun and I have written a proposal are following up the
recent discussion thread "[RFC] #Self” with a proposal to introduce
StaticSelf, an invariant Self.
 
The recent discussion can be found
here: http://thread.gmane.org/gmane.comp.lang.swift.evolution/16565
 
The proposal can be found
here: 
 https://github.com/anandabits/swift-evolution/blob/static-self/proposals/-static-self.md
 
We look forward to continuing the discussion.  We plan to submit a
PR in the near future after incorporating your final feedback.
 
Thanks,
Matthew
 
 
  Introducing StaticSelf, an Invariant Self
 
  * Proposal: TBD
  * Authors: Matthew Johnson , Erica
Sadun 
  * Status: TBD
  * Review manager: TBD
 
 
Introduction
 
This proposal introduces a new keyword that provides consistent
invariant type semantics in all contexts.
 
/The Swift-evolution thread about this topic can be found
here: [RFC] #Self
/
 
 
Motivation
 
The distinction between covariant and non-covariant type references
come into play when
conforming non-final classes to protocols. Fixing a protocol
requirement to a covarying type
means that a method returning |Self| must be overriden by all
subclasses in order to return
the correct, matching type.
 
This proposal builds on the covariant construct |Self| accepted
in SE–0068

 
to introduce an invariant type identifier. It enables protocol
declarations to consistently
refer to a type that is fixed at compile time. This ensures that
subclasses can inherit
protocol implementations without having to re-implement that code at
each level of
inheritance.
 
Under this proposal, a new identifier keyword is fixed in use /at
the point of protocol conformance/
to the static type of that construct.
 
|class A: MyProtocol|
 
The invariant |StaticSelf| identifier will always refer to |A|,
unlike 

Re: [swift-evolution] [Draft] Introducing StaticSelf, an Invariant Self

2016-05-13 Thread Vladimir.S via swift-evolution

I don't understand.
Right now we are allowed to have Optional(Self) :

protocol A {
  func g()->Self?
}

class B: A {
  func g()->Self? {return self}
}

print(B().g()) //Optional(main.B)

How do you want to divide your `->Self?` and this currently possible 
`->Self?` ?



But I do like the idea to separate meaning of `Self` in protocol with some 
marker.. What about `->?Self` and `->!Self` - no confusing with Optional<>


On 13.05.2016 14:21, LM via swift-evolution wrote:


The other advantage of Self! over StaticSelf is that in code completion,
Self, Self? Self! Will come together, giving people a quick tool to
discover/remind themselves of the semantic difference right at the point of
use.

It might also address Joe's comment about StaticSelf not being much of a
shortcut.


On May 13, 2016, at 1:15 PM, LM > wrote:


Considering the precedent of using ! and ? in swift, could it be that:

Self!  would designate what is known for sure, the invariant compile time
type of self

Self? Would designate the yet unknown (*optional* if you will) covariant
type of self


Regards
LM
(From mobile)

On May 13, 2016, at 3:59 AM, Xiaodi Wu via swift-evolution
> wrote:


I like the way the motivation for this feature has been explained here.
Now that the reasoning behind it is evident, I have to say I'm leaning
towards the "InvariantSelf" name--after all, you describe this feature
in the title as "an invariant self."


On Thu, May 12, 2016 at 7:49 PM, Matthew Johnson via swift-evolution
> wrote:

Erica Sadun and I have written a proposal are following up the
recent discussion thread "[RFC] #Self” with a proposal to introduce
StaticSelf, an invariant Self.

The recent discussion can be found
here: http://thread.gmane.org/gmane.comp.lang.swift.evolution/16565

The proposal can be found
here: 
https://github.com/anandabits/swift-evolution/blob/static-self/proposals/-static-self.md

We look forward to continuing the discussion.  We plan to submit a
PR in the near future after incorporating your final feedback.

Thanks,
Matthew


  Introducing StaticSelf, an Invariant Self

  * Proposal: TBD
  * Authors: Matthew Johnson , Erica
Sadun 
  * Status: TBD
  * Review manager: TBD


Introduction

This proposal introduces a new keyword that provides consistent
invariant type semantics in all contexts.

/The Swift-evolution thread about this topic can be found
here: [RFC] #Self
/


Motivation

The distinction between covariant and non-covariant type references
come into play when
conforming non-final classes to protocols. Fixing a protocol
requirement to a covarying type
means that a method returning |Self| must be overriden by all
subclasses in order to return
the correct, matching type.

This proposal builds on the covariant construct |Self| accepted
in SE–0068


to introduce an invariant type identifier. It enables protocol
declarations to consistently
refer to a type that is fixed at compile time. This ensures that
subclasses can inherit
protocol implementations without having to re-implement that code at
each level of
inheritance.

Under this proposal, a new identifier keyword is fixed in use /at
the point of protocol conformance/
to the static type of that construct.

|class A: MyProtocol|

The invariant |StaticSelf| identifier will always refer to |A|,
unlike |Self|, which is covarying and refers to
the type of the actual instance. Since multiple inheritance for
non-protocol types is disallowed,
this establishes this invariant type identifier with no possibility
for conflict.

Consider the following example, under the current system:

|protocol StringCreatable { static func createWithString(s: String)
-> Self } extension NSURL: StringCreatable { // cannot conform
because NSURL is non-final // error: method 'createWithString' in
non-final class 'NSURL' must return `Self` to conform to protocol 'A' }|

Introducing a static, invariant version of |Self| permits the
desired conformance:

|protocol StringCreatable { static func createWithString(s: String)
-> StaticSelf } extension NSURL: StringCreatable { // can now
conform conform because NSURL is fixed and matches the static //
type of the conforming construct. Subclasses need not re-implement
// NOTE: the return type can be declared as StaticSelf *or* as NSURL
// they are interchangeable static func createWithString(s: 

Re: [swift-evolution] [Draft] Introducing StaticSelf, an Invariant Self

2016-05-13 Thread LM via swift-evolution

The other advantage of Self! over StaticSelf is that in code completion, Self, 
Self? Self! Will come together, giving people a quick tool to discover/remind 
themselves of the semantic difference right at the point of use. 

It might also address Joe's comment about StaticSelf not being much of a 
shortcut.


> On May 13, 2016, at 1:15 PM, LM  wrote:
> 
> Considering the precedent of using ! and ? in swift, could it be that:
> 
> Self!  would designate what is known for sure, the invariant compile time 
> type of self
> 
> Self? Would designate the yet unknown (*optional* if you will) covariant type 
> of self
> 
> 
> Regards
> LM
> (From mobile)
> 
>> On May 13, 2016, at 3:59 AM, Xiaodi Wu via swift-evolution 
>>  wrote:
>> 
>> I like the way the motivation for this feature has been explained here. Now 
>> that the reasoning behind it is evident, I have to say I'm leaning towards 
>> the "InvariantSelf" name--after all, you describe this feature in the title 
>> as "an invariant self."
>> 
>> 
>>> On Thu, May 12, 2016 at 7:49 PM, Matthew Johnson via swift-evolution 
>>>  wrote:
>>> Erica Sadun and I have written a proposal are following up the recent 
>>> discussion thread "[RFC] #Self” with a proposal to introduce StaticSelf, an 
>>> invariant Self.
>>> 
>>> The recent discussion can be found here: 
>>> http://thread.gmane.org/gmane.comp.lang.swift.evolution/16565
>>> 
>>> The proposal can be found here: 
>>> https://github.com/anandabits/swift-evolution/blob/static-self/proposals/-static-self.md
>>> 
>>> We look forward to continuing the discussion.  We plan to submit a PR in 
>>> the near future after incorporating your final feedback.
>>> 
>>> Thanks,
>>> Matthew
>>> Introducing StaticSelf, an Invariant Self
>>> 
>>> Proposal: TBD
>>> Authors: Matthew Johnson, Erica Sadun
>>> Status: TBD
>>> Review manager: TBD
>>> Introduction
>>> 
>>> This proposal introduces a new keyword that provides consistent invariant 
>>> type semantics in all contexts.
>>> 
>>> The Swift-evolution thread about this topic can be found here: [RFC] #Self
>>> 
>>> Motivation
>>> 
>>> The distinction between covariant and non-covariant type references come 
>>> into play when
>>> conforming non-final classes to protocols. Fixing a protocol requirement to 
>>> a covarying type
>>> means that a method returning Self must be overriden by all subclasses in 
>>> order to return
>>> the correct, matching type.
>>> 
>>> This proposal builds on the covariant construct Self accepted in SE–0068
>>> to introduce an invariant type identifier. It enables protocol declarations 
>>> to consistently
>>> refer to a type that is fixed at compile time. This ensures that subclasses 
>>> can inherit
>>> protocol implementations without having to re-implement that code at each 
>>> level of
>>> inheritance.
>>> 
>>> Under this proposal, a new identifier keyword is fixed in use at the point 
>>> of protocol conformance
>>> to the static type of that construct. 
>>> 
>>> class A: MyProtocol
>>> The invariant StaticSelf identifier will always refer to A, unlike Self, 
>>> which is covarying and refers to
>>> the type of the actual instance. Since multiple inheritance for 
>>> non-protocol types is disallowed,
>>> this establishes this invariant type identifier with no possibility for 
>>> conflict.
>>> 
>>> Consider the following example, under the current system:
>>> 
>>> protocol StringCreatable {
>>> static func createWithString(s: String) -> Self
>>> }
>>> 
>>> extension NSURL: StringCreatable {
>>>  // cannot conform because NSURL is non-final
>>>  // error: method 'createWithString' in non-final class 'NSURL' must return 
>>> `Self` to conform to protocol 'A'
>>> }
>>> Introducing a static, invariant version of Self permits the desired 
>>> conformance:
>>> 
>>> protocol StringCreatable {
>>> static func createWithString(s: String) -> StaticSelf
>>> }
>>> 
>>> extension NSURL: StringCreatable {
>>>  // can now conform conform because NSURL is fixed and matches the static
>>>  // type of the conforming construct. Subclasses need not re-implement
>>>  // NOTE: the return type can be declared as StaticSelf *or* as NSURL
>>>  //   they are interchangeable
>>>  static func createWithString(s: String) -> StaticSelf { 
>>>  // ...
>>>  }
>>> }
>>> Additional Utility
>>> 
>>> The utility of StaticSelf is not limited to protocols. A secondary use 
>>> enables code to refer to the lexical context’s current type without 
>>> explicitly mentioning its name. This provides a useful shortcut when 
>>> referencing static type members with especially long names and when 
>>> re-purposing code between types.
>>> 
>>> class StructWithAVeryLongName {
>>> static func foo() -> String {
>>>   // ...
>>> }
>>> func bar() {
>>>   // ...
>>>   let s = StaticSelf.foo()
>>>   //
>>> }
>>> }
>>> Detailed Design
>>> 
>>> This proposal 

Re: [swift-evolution] [Draft] Introducing StaticSelf, an Invariant Self

2016-05-13 Thread LM via swift-evolution
Considering the precedent of using ! and ? in swift, could it be that:

Self!  would designate what is known for sure, the invariant compile time type 
of self

Self? Would designate the yet unknown (*optional* if you will) covariant type 
of self


Regards
LM
(From mobile)

> On May 13, 2016, at 3:59 AM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> I like the way the motivation for this feature has been explained here. Now 
> that the reasoning behind it is evident, I have to say I'm leaning towards 
> the "InvariantSelf" name--after all, you describe this feature in the title 
> as "an invariant self."
> 
> 
>> On Thu, May 12, 2016 at 7:49 PM, Matthew Johnson via swift-evolution 
>>  wrote:
>> Erica Sadun and I have written a proposal are following up the recent 
>> discussion thread "[RFC] #Self” with a proposal to introduce StaticSelf, an 
>> invariant Self.
>> 
>> The recent discussion can be found here: 
>> http://thread.gmane.org/gmane.comp.lang.swift.evolution/16565
>> 
>> The proposal can be found here: 
>> https://github.com/anandabits/swift-evolution/blob/static-self/proposals/-static-self.md
>> 
>> We look forward to continuing the discussion.  We plan to submit a PR in the 
>> near future after incorporating your final feedback.
>> 
>> Thanks,
>> Matthew
>> Introducing StaticSelf, an Invariant Self
>> 
>> Proposal: TBD
>> Authors: Matthew Johnson, Erica Sadun
>> Status: TBD
>> Review manager: TBD
>> Introduction
>> 
>> This proposal introduces a new keyword that provides consistent invariant 
>> type semantics in all contexts.
>> 
>> The Swift-evolution thread about this topic can be found here: [RFC] #Self
>> 
>> Motivation
>> 
>> The distinction between covariant and non-covariant type references come 
>> into play when
>> conforming non-final classes to protocols. Fixing a protocol requirement to 
>> a covarying type
>> means that a method returning Self must be overriden by all subclasses in 
>> order to return
>> the correct, matching type.
>> 
>> This proposal builds on the covariant construct Self accepted in SE–0068
>> to introduce an invariant type identifier. It enables protocol declarations 
>> to consistently
>> refer to a type that is fixed at compile time. This ensures that subclasses 
>> can inherit
>> protocol implementations without having to re-implement that code at each 
>> level of
>> inheritance.
>> 
>> Under this proposal, a new identifier keyword is fixed in use at the point 
>> of protocol conformance
>> to the static type of that construct. 
>> 
>> class A: MyProtocol
>> The invariant StaticSelf identifier will always refer to A, unlike Self, 
>> which is covarying and refers to
>> the type of the actual instance. Since multiple inheritance for non-protocol 
>> types is disallowed,
>> this establishes this invariant type identifier with no possibility for 
>> conflict.
>> 
>> Consider the following example, under the current system:
>> 
>> protocol StringCreatable {
>> static func createWithString(s: String) -> Self
>> }
>> 
>> extension NSURL: StringCreatable {
>>  // cannot conform because NSURL is non-final
>>  // error: method 'createWithString' in non-final class 'NSURL' must return 
>> `Self` to conform to protocol 'A'
>> }
>> Introducing a static, invariant version of Self permits the desired 
>> conformance:
>> 
>> protocol StringCreatable {
>> static func createWithString(s: String) -> StaticSelf
>> }
>> 
>> extension NSURL: StringCreatable {
>>  // can now conform conform because NSURL is fixed and matches the static
>>  // type of the conforming construct. Subclasses need not re-implement
>>  // NOTE: the return type can be declared as StaticSelf *or* as NSURL
>>  //   they are interchangeable
>>  static func createWithString(s: String) -> StaticSelf { 
>>  // ...
>>  }
>> }
>> Additional Utility
>> 
>> The utility of StaticSelf is not limited to protocols. A secondary use 
>> enables code to refer to the lexical context’s current type without 
>> explicitly mentioning its name. This provides a useful shortcut when 
>> referencing static type members with especially long names and when 
>> re-purposing code between types.
>> 
>> class StructWithAVeryLongName {
>> static func foo() -> String {
>>   // ...
>> }
>> func bar() {
>>   // ...
>>   let s = StaticSelf.foo()
>>   //
>> }
>> }
>> Detailed Design
>> 
>> This proposal introduces StaticSelf, a new keyword that may be used in 
>> protocols to refer to the invariant static type of a conforming construct. 
>> StaticSelf may also be used in the lexical context of any type declaration. 
>> In such use, the keyword is identical to spelling out the full name of that 
>> type.
>> 
>> Impact on existing code
>> 
>> Being additive, there should be no impact on existing code.
>> 
>> Alternatives considered
>> 
>> The keyword is not fixed at this time. Alternatives that have been discussed 
>> include 

Re: [swift-evolution] [Draft] Introducing StaticSelf, an Invariant Self

2016-05-13 Thread Vladimir.S via swift-evolution

On 13.05.2016 9:45, Patrick Smith wrote:

Could protocol Self change to just the first behaviour for classes?

If a conformance absolutely needs to have a method returning ‘only me but not 
my subclasses’, then it sets that conforming method to be final.


Hm.. Do we *need* to change `->Self` behavior? It actually depends on what 
such requirement will mean for classes. Right now it is '->return instance 
of self class'. If we all agree that it should means '->return instance of 
self class or of any base class' - then we obviously can require such a 
change.






On 13 May 2016, at 4:38 PM, Vladimir.S  wrote:

The proposed StaticSelf when used as `->StaticSelf` in protocol means ‘myself or 
my some *base* class’. I.e. if this requirement was implemented in one of base 
classes, any subclass automatically conforms to the protocol as it has `->(myself 
or some base class)` in his hierarchy.

This is the difference with `->Self` in protocol which requires 'myself'.

On 13.05.2016 7:21, Patrick Smith via swift-evolution wrote:

I didn’t really understand some of the lead in discussion examples
regarding protocols A and B each being interwoven, but I would prefer to
see StaticSelf only used for concrete types, and protocols only to use
Self. If Self has problems with non-final classes, then maybe how it
works in protocols could change. A class could interpret a protocol’s
‘Self’ as ‘myself or my subclasses’?

Maybe instead of introducing StaticSelf it could be renamed simply Self,
and ‘Self’ as used in protocols could change to something else?
‘Instance’ perhaps?


On 13 May 2016, at 12:21 PM, Joe Groff via swift-evolution
 wrote:



On May 12, 2016, at 5:49 PM, Matthew Johnson via swift-evolution
 wrote:

The invariant StaticSelf identifier will always refer to A, unlike
Self, which is covarying and refers to the type of the actual
instance. Since multiple inheritance for non-protocol types is
disallowed, this establishes this invariant type identifier with no
possibility for conflict.

Consider the following example, under the current system:

protocol StringCreatable {

static func createWithString(s: String) -> Self

}


extension NSURL: StringCreatable {

// cannot conform because NSURL is non-final


// error: method 'createWithString' in non-final class 'NSURL' must
return `Self` to conform to protocol 'A'

}

Introducing a static, invariant version of Self permits the desired
conformance:

protocol StringCreatable {

static func createWithString(s: String) -> StaticSelf

}


extension NSURL: StringCreatable {

// can now conform conform because NSURL is fixed and matches the
static


// type of the conforming construct. Subclasses need not
re-implement


// NOTE: the return type can be declared as StaticSelf *or* as
NSURL


//   they are interchangeable


static func createWithString(s: String) -> StaticSelf {

// ...

} }




As I've noted before, I don't think this makes sense to encode in the
protocol. `Self` is already effectively invariant within a protocol.
If a protocol doesn't have the foresight to use StaticSelf, then you
still have the same problems retroactively conforming class
hierarchies to the protocol. Whether a conformance is inherited or not
feels more natural as a property of a conformance, not something that
can be legislated a priori by a protocol definition.

Something like StaticSelf might still be useful as shorthand within a
class definition with a long-winded name, though `StaticSelf` feels
kind of long as a shortcut to me.

-Joe ___ 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] [Draft] Introducing StaticSelf, an Invariant Self

2016-05-13 Thread Vladimir.S via swift-evolution

> I'm not convinced by this example.

Probably my & Matthew's previous discussion in `[swift-evolution] [RFC] 
#Self` topic will help you. I was trying there to find out (in primitive 
examples) what Matthew is trying to achive with this `->StaticSelf` in 
protocol.


In two words - he wants to achieve requirement 'return Self class or any of 
base classes', as current `->Self` requires 'strictly return Self class'


On 13.05.2016 12:46, Nicola Salmoria via swift-evolution wrote:

Matthew Johnson via swift-evolution  writes:


Consider the following example, under the current system:
protocol StringCreatable {
static func createWithString(s: String) -> Self
}

extension NSURL: StringCreatable {
 // cannot conform because NSURL is non-final
 // error: method 'createWithString' in non-final class 'NSURL' must
return `Self` to conform to protocol 'A'
}Introducing a static, invariant version of Self permits the desired
conformance:
protocol StringCreatable {
static func createWithString(s: String) -> StaticSelf
}


I'm not convinced by this example.

I think the problem to solve here is the interaction of protocols with
classes.
A related issue was illustrated by Tony Allevato here
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160502
/016294.html

I think that before attempting to solve this specific problem introducing a
new notation, the general design of the interaction between protocols and
class inheritance should be reviewed.


Nicola

___
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] [Draft] Introducing StaticSelf, an Invariant Self

2016-05-13 Thread Ricardo Parada via swift-evolution
That makes sense to me. 

> On May 13, 2016, at 2:45 AM, Patrick Smith via swift-evolution 
>  wrote:
> 
> If a conformance absolutely needs to have a method returning ‘only me but not 
> my subclasses’, then it sets that conforming method to be final.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Draft] Introducing StaticSelf, an Invariant Self

2016-05-13 Thread Ricardo Parada via swift-evolution
I would prefer BaseSelf. 


> On May 13, 2016, at 2:28 AM, Vladimir.S via swift-evolution 
>  wrote:
> 
> via
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Draft] Introducing StaticSelf, an Invariant Self

2016-05-13 Thread Nicola Salmoria via swift-evolution
Matthew Johnson via swift-evolution  writes:

> Consider the following example, under the current system:
> protocol StringCreatable {
> static func createWithString(s: String) -> Self
> }
> 
> extension NSURL: StringCreatable {
>  // cannot conform because NSURL is non-final
>  // error: method 'createWithString' in non-final class 'NSURL' must
> return `Self` to conform to protocol 'A'
> }Introducing a static, invariant version of Self permits the desired
> conformance:
> protocol StringCreatable {
> static func createWithString(s: String) -> StaticSelf
> }

I'm not convinced by this example.

I think the problem to solve here is the interaction of protocols with
classes.
A related issue was illustrated by Tony Allevato here
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160502
/016294.html

I think that before attempting to solve this specific problem introducing a
new notation, the general design of the interaction between protocols and
class inheritance should be reviewed.


Nicola

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


Re: [swift-evolution] [Draft] Introducing StaticSelf, an Invariant Self

2016-05-13 Thread Vladimir.S via swift-evolution
Why did you decide to drop the `#` ? As `StaticSelf` will be resolved on 
compilation time like #file etc ? I feel like this is inconsistent solution.


Also, do you expect this will work:

protocol A {
  func g()->StaticSelf
}

class B: A {
  func g()->StaticSelf {return B()}
}

class C: B {
  //func f(s: C) {}
}

func x(a: A ){
var xx : A = a.g() // ?
print(xx)
}

func z(t: T) {
let u = t.g() // ?
print(u)
}

let c = C()
z(c)
x(c)


On 13.05.2016 3:49, Matthew Johnson via swift-evolution wrote:

Erica Sadun and I have written a proposal are following up the recent
discussion thread "[RFC] #Self” with a proposal to introduce StaticSelf, an
invariant Self.

The recent discussion can be found
here: http://thread.gmane.org/gmane.comp.lang.swift.evolution/16565

The proposal can be found
here: 
https://github.com/anandabits/swift-evolution/blob/static-self/proposals/-static-self.md

We look forward to continuing the discussion.  We plan to submit a PR in
the near future after incorporating your final feedback.

Thanks,
Matthew


  Introducing StaticSelf, an Invariant Self

  * Proposal: TBD
  * Authors: Matthew Johnson , Erica Sadun

  * Status: TBD
  * Review manager: TBD


Introduction

This proposal introduces a new keyword that provides consistent invariant
type semantics in all contexts.

/The Swift-evolution thread about this topic can be found here: [RFC] #Self
/


Motivation

The distinction between covariant and non-covariant type references come
into play when
conforming non-final classes to protocols. Fixing a protocol requirement to
a covarying type
means that a method returning |Self| must be overriden by all subclasses in
order to return
the correct, matching type.

This proposal builds on the covariant construct |Self| accepted in SE–0068

to introduce an invariant type identifier. It enables protocol declarations
to consistently
refer to a type that is fixed at compile time. This ensures that subclasses
can inherit
protocol implementations without having to re-implement that code at each
level of
inheritance.

Under this proposal, a new identifier keyword is fixed in use /at the point
of protocol conformance/
to the static type of that construct.

|class A: MyProtocol|

The invariant |StaticSelf| identifier will always refer to |A|,
unlike |Self|, which is covarying and refers to
the type of the actual instance. Since multiple inheritance for
non-protocol types is disallowed,
this establishes this invariant type identifier with no possibility for
conflict.

Consider the following example, under the current system:

|protocol StringCreatable { static func createWithString(s: String) -> Self
} extension NSURL: StringCreatable { // cannot conform because NSURL is
non-final // error: method 'createWithString' in non-final class 'NSURL'
must return `Self` to conform to protocol 'A' }|

Introducing a static, invariant version of |Self| permits the desired
conformance:

|protocol StringCreatable { static func createWithString(s: String) ->
StaticSelf } extension NSURL: StringCreatable { // can now conform conform
because NSURL is fixed and matches the static // type of the conforming
construct. Subclasses need not re-implement // NOTE: the return type can be
declared as StaticSelf *or* as NSURL // they are interchangeable static
func createWithString(s: String) -> StaticSelf { // ... } }|


  Additional Utility

The utility of |StaticSelf| is not limited to protocols. A secondary use
enables code to refer to the lexical context’s current type without
explicitly mentioning its name. This provides a useful shortcut when
referencing static type members with especially long names and when
re-purposing code between types.

|class StructWithAVeryLongName { static func foo() -> String { // ... } func
bar() { // ... let s = StaticSelf.foo() // } }|


Detailed Design

This proposal introduces |StaticSelf|, a new keyword that may be used in
protocols to refer to the invariant static type of a conforming
construct. |StaticSelf| may also be used in the lexical context of any type
declaration. In such use, the keyword is identical to spelling out the full
name of that type.


Impact on existing code

Being additive, there should be no impact on existing code.


Alternatives considered

The keyword is not fixed at this time. Alternatives that have been
discussed include |StaticType|, |InvariantSelf|, |SelfType|, or |Type|. The
community is welcome to bikeshed on the most clear and concise name for
this keyword.



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


___
swift-evolution mailing list

Re: [swift-evolution] [Draft] Introducing StaticSelf, an Invariant Self

2016-05-13 Thread Vladimir.S via swift-evolution
I don't feel that InvariantSelf reflects the fact that class conformed to 
protocol with `f()->InvariantSelf` requirement will actually return
'self or some base class'. Especially when this `InvariantSelf` means 
`exactly this concrete static type name` inside type declaration.


Probably the better name is BaseType (BaseSelf, ThisType.. #Type ?)

But actually I don't fully understand how this would work in generic functions:

protocol A {
  func g()->StaticSelf
}

class B: A {
  func g()->StaticSelf {return B()}
}

class C: B {
}


func x(a: A ){
var xx : A = a.g() // will this work? as g returns *some in hierarchy*
print(xx)
}

func z(t: T) {
let u = t.g() // will this work?
print(u)
}

let c = C()
z(c)
x(c)




On 13.05.2016 4:59, Xiaodi Wu via swift-evolution wrote:

I like the way the motivation for this feature has been explained here. Now
that the reasoning behind it is evident, I have to say I'm leaning towards
the "InvariantSelf" name--after all, you describe this feature in the title
as "an invariant self."


On Thu, May 12, 2016 at 7:49 PM, Matthew Johnson via swift-evolution
> wrote:

Erica Sadun and I have written a proposal are following up the recent
discussion thread "[RFC] #Self” with a proposal to introduce
StaticSelf, an invariant Self.

The recent discussion can be found
here: http://thread.gmane.org/gmane.comp.lang.swift.evolution/16565

The proposal can be found
here: 
https://github.com/anandabits/swift-evolution/blob/static-self/proposals/-static-self.md

We look forward to continuing the discussion.  We plan to submit a PR
in the near future after incorporating your final feedback.

Thanks,
Matthew


  Introducing StaticSelf, an Invariant Self

  * Proposal: TBD
  * Authors: Matthew Johnson , Erica
Sadun 
  * Status: TBD
  * Review manager: TBD


Introduction

This proposal introduces a new keyword that provides consistent
invariant type semantics in all contexts.

/The Swift-evolution thread about this topic can be found here: [RFC]
#Self /


Motivation

The distinction between covariant and non-covariant type references
come into play when
conforming non-final classes to protocols. Fixing a protocol
requirement to a covarying type
means that a method returning |Self| must be overriden by all
subclasses in order to return
the correct, matching type.

This proposal builds on the covariant construct |Self| accepted
in SE–0068


to introduce an invariant type identifier. It enables protocol
declarations to consistently
refer to a type that is fixed at compile time. This ensures that
subclasses can inherit
protocol implementations without having to re-implement that code at
each level of
inheritance.

Under this proposal, a new identifier keyword is fixed in use /at the
point of protocol conformance/
to the static type of that construct.

|class A: MyProtocol|

The invariant |StaticSelf| identifier will always refer to |A|,
unlike |Self|, which is covarying and refers to
the type of the actual instance. Since multiple inheritance for
non-protocol types is disallowed,
this establishes this invariant type identifier with no possibility for
conflict.

Consider the following example, under the current system:

|protocol StringCreatable { static func createWithString(s: String) ->
Self } extension NSURL: StringCreatable { // cannot conform because
NSURL is non-final // error: method 'createWithString' in non-final
class 'NSURL' must return `Self` to conform to protocol 'A' }|

Introducing a static, invariant version of |Self| permits the desired
conformance:

|protocol StringCreatable { static func createWithString(s: String) ->
StaticSelf } extension NSURL: StringCreatable { // can now conform
conform because NSURL is fixed and matches the static // type of the
conforming construct. Subclasses need not re-implement // NOTE: the
return type can be declared as StaticSelf *or* as NSURL // they are
interchangeable static func createWithString(s: String) -> StaticSelf {
// ... } }|


  Additional Utility

The utility of |StaticSelf| is not limited to protocols. A secondary
use enables code to refer to the lexical context’s current type without
explicitly mentioning its name. This provides a useful shortcut when
referencing static type members with especially long names and when
re-purposing code between types.

|class StructWithAVeryLongName { static func foo() -> String { // ... }
func bar() { // ... let s = 

Re: [swift-evolution] [Draft] Introducing StaticSelf, an Invariant Self

2016-05-13 Thread Vladimir.S via swift-evolution

How about BaseType? (as just `Type` can not be used here) Or ThisType?

And, do you think we actually should use `#` here in analogue to #file as 
this `StaticSelf` will be pre-processed on compilation stage to be replaced 
with actual type name?


On 13.05.2016 5:21, Joe Groff via swift-evolution wrote:

Something like StaticSelf might still be useful as shorthand within a class 
definition with a long-winded name, though `StaticSelf` feels kind of long as a 
shortcut to me.

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


Re: [swift-evolution] [Draft] Introducing StaticSelf, an Invariant Self

2016-05-13 Thread Patrick Smith via swift-evolution
Could protocol Self change to just the first behaviour for classes?

If a conformance absolutely needs to have a method returning ‘only me but not 
my subclasses’, then it sets that conforming method to be final.


> On 13 May 2016, at 4:38 PM, Vladimir.S  wrote:
> 
> The proposed StaticSelf when used as `->StaticSelf` in protocol means ‘myself 
> or my some *base* class’. I.e. if this requirement was implemented in one of 
> base classes, any subclass automatically conforms to the protocol as it has 
> `->(myself or some base class)` in his hierarchy.
> 
> This is the difference with `->Self` in protocol which requires 'myself'.
> 
> On 13.05.2016 7:21, Patrick Smith via swift-evolution wrote:
>> I didn’t really understand some of the lead in discussion examples
>> regarding protocols A and B each being interwoven, but I would prefer to
>> see StaticSelf only used for concrete types, and protocols only to use
>> Self. If Self has problems with non-final classes, then maybe how it
>> works in protocols could change. A class could interpret a protocol’s
>> ‘Self’ as ‘myself or my subclasses’?
>> 
>> Maybe instead of introducing StaticSelf it could be renamed simply Self,
>> and ‘Self’ as used in protocols could change to something else?
>> ‘Instance’ perhaps?
>> 
>>> On 13 May 2016, at 12:21 PM, Joe Groff via swift-evolution
>>>  wrote:
>>> 
>>> 
 On May 12, 2016, at 5:49 PM, Matthew Johnson via swift-evolution
  wrote:
 
 The invariant StaticSelf identifier will always refer to A, unlike
 Self, which is covarying and refers to the type of the actual
 instance. Since multiple inheritance for non-protocol types is
 disallowed, this establishes this invariant type identifier with no
 possibility for conflict.
 
 Consider the following example, under the current system:
 
 protocol StringCreatable {
 
 static func createWithString(s: String) -> Self
 
 }
 
 
 extension NSURL: StringCreatable {
 
 // cannot conform because NSURL is non-final
 
 
 // error: method 'createWithString' in non-final class 'NSURL' must
 return `Self` to conform to protocol 'A'
 
 }
 
 Introducing a static, invariant version of Self permits the desired
 conformance:
 
 protocol StringCreatable {
 
 static func createWithString(s: String) -> StaticSelf
 
 }
 
 
 extension NSURL: StringCreatable {
 
 // can now conform conform because NSURL is fixed and matches the
 static
 
 
 // type of the conforming construct. Subclasses need not
 re-implement
 
 
 // NOTE: the return type can be declared as StaticSelf *or* as
 NSURL
 
 
 //   they are interchangeable
 
 
 static func createWithString(s: String) -> StaticSelf {
 
 // ...
 
 } }
 
 
>>> 
>>> As I've noted before, I don't think this makes sense to encode in the
>>> protocol. `Self` is already effectively invariant within a protocol.
>>> If a protocol doesn't have the foresight to use StaticSelf, then you
>>> still have the same problems retroactively conforming class
>>> hierarchies to the protocol. Whether a conformance is inherited or not
>>> feels more natural as a property of a conformance, not something that
>>> can be legislated a priori by a protocol definition.
>>> 
>>> Something like StaticSelf might still be useful as shorthand within a
>>> class definition with a long-winded name, though `StaticSelf` feels
>>> kind of long as a shortcut to me.
>>> 
>>> -Joe ___ 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] [Draft] Introducing StaticSelf, an Invariant Self

2016-05-13 Thread Vladimir.S via swift-evolution
In this case I propose to call it BaseType (or BaseSelf) as actually this 
'thing' in meaning `->StaticSelf` means 'self or any base class'


On 13.05.2016 7:56, Thorsten Seitz via swift-evolution wrote:

+1

Good description of the motivating problem!

As for bikeshedding: ConformingSelf, ConformingType, BaseSelf, BaseType

-Thorsten

Am 13.05.2016 um 02:49 schrieb Matthew Johnson via swift-evolution
>:


Erica Sadun and I have written a proposal are following up the recent
discussion thread "[RFC] #Self” with a proposal to introduce StaticSelf,
an invariant Self.

The recent discussion can be found
here: http://thread.gmane.org/gmane.comp.lang.swift.evolution/16565

The proposal can be found
here: 
https://github.com/anandabits/swift-evolution/blob/static-self/proposals/-static-self.md

We look forward to continuing the discussion.  We plan to submit a PR in
the near future after incorporating your final feedback.

Thanks,
Matthew


  Introducing StaticSelf, an Invariant Self

  * Proposal: TBD
  * Authors: Matthew Johnson , Erica Sadun

  * Status: TBD
  * Review manager: TBD


Introduction

This proposal introduces a new keyword that provides consistent invariant
type semantics in all contexts.

/The Swift-evolution thread about this topic can be found here: [RFC]
#Self /


Motivation

The distinction between covariant and non-covariant type references come
into play when
conforming non-final classes to protocols. Fixing a protocol requirement
to a covarying type
means that a method returning |Self| must be overriden by all subclasses
in order to return
the correct, matching type.

This proposal builds on the covariant construct |Self| accepted
in SE–0068

to introduce an invariant type identifier. It enables protocol
declarations to consistently
refer to a type that is fixed at compile time. This ensures that
subclasses can inherit
protocol implementations without having to re-implement that code at each
level of
inheritance.

Under this proposal, a new identifier keyword is fixed in use /at the
point of protocol conformance/
to the static type of that construct.

|class A: MyProtocol|

The invariant |StaticSelf| identifier will always refer to |A|,
unlike |Self|, which is covarying and refers to
the type of the actual instance. Since multiple inheritance for
non-protocol types is disallowed,
this establishes this invariant type identifier with no possibility for
conflict.

Consider the following example, under the current system:

|protocol StringCreatable { static func createWithString(s: String) ->
Self } extension NSURL: StringCreatable { // cannot conform because NSURL
is non-final // error: method 'createWithString' in non-final class
'NSURL' must return `Self` to conform to protocol 'A' }|

Introducing a static, invariant version of |Self| permits the desired
conformance:

|protocol StringCreatable { static func createWithString(s: String) ->
StaticSelf } extension NSURL: StringCreatable { // can now conform
conform because NSURL is fixed and matches the static // type of the
conforming construct. Subclasses need not re-implement // NOTE: the
return type can be declared as StaticSelf *or* as NSURL // they are
interchangeable static func createWithString(s: String) -> StaticSelf {
// ... } }|


  Additional Utility

The utility of |StaticSelf| is not limited to protocols. A secondary use
enables code to refer to the lexical context’s current type without
explicitly mentioning its name. This provides a useful shortcut when
referencing static type members with especially long names and when
re-purposing code between types.

|class StructWithAVeryLongName { static func foo() -> String { // ... }
func bar() { // ... let s = StaticSelf.foo() // } }|


Detailed Design

This proposal introduces |StaticSelf|, a new keyword that may be used in
protocols to refer to the invariant static type of a conforming
construct. |StaticSelf| may also be used in the lexical context of any
type declaration. In such use, the keyword is identical to spelling out
the full name of that type.


Impact on existing code

Being additive, there should be no impact on existing code.


Alternatives considered

The keyword is not fixed at this time. Alternatives that have been
discussed include |StaticType|, |InvariantSelf|, |SelfType|, or |Type|.
The community is welcome to bikeshed on the most clear and concise name
for this keyword.

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



___
swift-evolution mailing list
swift-evolution@swift.org

Re: [swift-evolution] [Draft] Introducing StaticSelf, an Invariant Self

2016-05-13 Thread David Hart via swift-evolution
Totally agree. It feels weird to have protocols decide on how "Self" 
conformance a are inherited. It should a decision for the conforming type.

> On 13 May 2016, at 04:21, Joe Groff via swift-evolution 
>  wrote:
> 
> 
>> On May 12, 2016, at 5:49 PM, Matthew Johnson via swift-evolution 
>>  wrote:
>> 
>> The invariant StaticSelf identifier will always refer to A, unlike Self, 
>> which is covarying and refers to
>> the type of the actual instance. Since multiple inheritance for non-protocol 
>> types is disallowed,
>> this establishes this invariant type identifier with no possibility for 
>> conflict.
>> 
>> Consider the following example, under the current system:
>> 
>> protocol StringCreatable 
>> {
>> 
>> static func createWithString(s: String) -> Self
>> 
>> }
>> 
>> 
>> extension NSURL: StringCreatable 
>> {
>> 
>> // cannot conform because NSURL is non-final
>> 
>> 
>> // error: method 'createWithString' in non-final class 'NSURL' must return 
>> `Self` to conform to protocol 'A'
>> 
>> }
>> 
>> Introducing a static, invariant version of Self permits the desired 
>> conformance:
>> 
>> protocol StringCreatable 
>> {
>> 
>> static func createWithString(s: String) -> StaticSelf
>> 
>> }
>> 
>> 
>> extension NSURL: StringCreatable 
>> {
>> 
>> // can now conform conform because NSURL is fixed and matches the static
>> 
>> 
>> // type of the conforming construct. Subclasses need not re-implement
>> 
>> 
>> // NOTE: the return type can be declared as StaticSelf *or* as NSURL
>> 
>> 
>> //   they are interchangeable
>> 
>> 
>> static func createWithString(s: String) -> StaticSelf
>> { 
>> 
>> // ...
>> 
>> }
>> }
> 
> As I've noted before, I don't think this makes sense to encode in the 
> protocol. `Self` is already effectively invariant within a protocol. If a 
> protocol doesn't have the foresight to use StaticSelf, then you still have 
> the same problems retroactively conforming class hierarchies to the protocol. 
> Whether a conformance is inherited or not feels more natural as a property of 
> a conformance, not something that can be legislated a priori by a protocol 
> definition.
> 
> Something like StaticSelf might still be useful as shorthand within a class 
> definition with a long-winded name, though `StaticSelf` feels kind of long as 
> a shortcut to me.
> 
> -Joe
> ___
> 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] [Draft] Introducing StaticSelf, an Invariant Self

2016-05-12 Thread Thorsten Seitz via swift-evolution
+1

Good description of the motivating problem!

As for bikeshedding: ConformingSelf, ConformingType, BaseSelf, BaseType

-Thorsten 

> Am 13.05.2016 um 02:49 schrieb Matthew Johnson via swift-evolution 
> :
> 
> Erica Sadun and I have written a proposal are following up the recent 
> discussion thread "[RFC] #Self” with a proposal to introduce StaticSelf, an 
> invariant Self.
> 
> The recent discussion can be found here: 
> http://thread.gmane.org/gmane.comp.lang.swift.evolution/16565
> 
> The proposal can be found here: 
> https://github.com/anandabits/swift-evolution/blob/static-self/proposals/-static-self.md
> 
> We look forward to continuing the discussion.  We plan to submit a PR in the 
> near future after incorporating your final feedback.
> 
> Thanks,
> Matthew
> Introducing StaticSelf, an Invariant Self
> 
> Proposal: TBD
> Authors: Matthew Johnson, Erica Sadun
> Status: TBD
> Review manager: TBD
> Introduction
> 
> This proposal introduces a new keyword that provides consistent invariant 
> type semantics in all contexts.
> 
> The Swift-evolution thread about this topic can be found here: [RFC] #Self
> 
> Motivation
> 
> The distinction between covariant and non-covariant type references come into 
> play when
> conforming non-final classes to protocols. Fixing a protocol requirement to a 
> covarying type
> means that a method returning Self must be overriden by all subclasses in 
> order to return
> the correct, matching type.
> 
> This proposal builds on the covariant construct Self accepted in SE–0068
> to introduce an invariant type identifier. It enables protocol declarations 
> to consistently
> refer to a type that is fixed at compile time. This ensures that subclasses 
> can inherit
> protocol implementations without having to re-implement that code at each 
> level of
> inheritance.
> 
> Under this proposal, a new identifier keyword is fixed in use at the point of 
> protocol conformance
> to the static type of that construct. 
> 
> class A: MyProtocol
> The invariant StaticSelf identifier will always refer to A, unlike Self, 
> which is covarying and refers to
> the type of the actual instance. Since multiple inheritance for non-protocol 
> types is disallowed,
> this establishes this invariant type identifier with no possibility for 
> conflict.
> 
> Consider the following example, under the current system:
> 
> protocol StringCreatable {
> static func createWithString(s: String) -> Self
> }
> 
> extension NSURL: StringCreatable {
>  // cannot conform because NSURL is non-final
>  // error: method 'createWithString' in non-final class 'NSURL' must return 
> `Self` to conform to protocol 'A'
> }
> Introducing a static, invariant version of Self permits the desired 
> conformance:
> 
> protocol StringCreatable {
> static func createWithString(s: String) -> StaticSelf
> }
> 
> extension NSURL: StringCreatable {
>  // can now conform conform because NSURL is fixed and matches the static
>  // type of the conforming construct. Subclasses need not re-implement
>  // NOTE: the return type can be declared as StaticSelf *or* as NSURL
>  //   they are interchangeable
>  static func createWithString(s: String) -> StaticSelf { 
>  // ...
>  }
> }
> Additional Utility
> 
> The utility of StaticSelf is not limited to protocols. A secondary use 
> enables code to refer to the lexical context’s current type without 
> explicitly mentioning its name. This provides a useful shortcut when 
> referencing static type members with especially long names and when 
> re-purposing code between types.
> 
> class StructWithAVeryLongName {
> static func foo() -> String {
>   // ...
> }
> func bar() {
>   // ...
>   let s = StaticSelf.foo()
>   //
> }
> }
> Detailed Design
> 
> This proposal introduces StaticSelf, a new keyword that may be used in 
> protocols to refer to the invariant static type of a conforming construct. 
> StaticSelf may also be used in the lexical context of any type declaration. 
> In such use, the keyword is identical to spelling out the full name of that 
> type.
> 
> Impact on existing code
> 
> Being additive, there should be no impact on existing code.
> 
> Alternatives considered
> 
> The keyword is not fixed at this time. Alternatives that have been discussed 
> include StaticType, InvariantSelf, SelfType, or Type. The community is 
> welcome to bikeshed on the most clear and concise name for this keyword.
> 
> ___
> 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] [Draft] Introducing StaticSelf, an Invariant Self

2016-05-12 Thread Patrick Smith via swift-evolution
I didn’t really understand some of the lead in discussion examples regarding 
protocols A and B each being interwoven, but I would prefer to see StaticSelf 
only used for concrete types, and protocols only to use Self. If Self has 
problems with non-final classes, then maybe how it works in protocols could 
change. A class could interpret a protocol’s ‘Self’ as ‘myself or my 
subclasses’?

Maybe instead of introducing StaticSelf it could be renamed simply Self, and 
‘Self’ as used in protocols could change to something else? ‘Instance’ perhaps?

> On 13 May 2016, at 12:21 PM, Joe Groff via swift-evolution 
>  wrote:
> 
> 
>> On May 12, 2016, at 5:49 PM, Matthew Johnson via swift-evolution 
>>  wrote:
>> 
>> The invariant StaticSelf identifier will always refer to A, unlike Self, 
>> which is covarying and refers to
>> the type of the actual instance. Since multiple inheritance for non-protocol 
>> types is disallowed,
>> this establishes this invariant type identifier with no possibility for 
>> conflict.
>> 
>> Consider the following example, under the current system:
>> 
>> protocol StringCreatable 
>> {
>> 
>> static func createWithString(s: String) -> Self
>> 
>> }
>> 
>> 
>> extension NSURL: StringCreatable 
>> {
>> 
>> // cannot conform because NSURL is non-final
>> 
>> 
>> // error: method 'createWithString' in non-final class 'NSURL' must return 
>> `Self` to conform to protocol 'A'
>> 
>> }
>> 
>> Introducing a static, invariant version of Self permits the desired 
>> conformance:
>> 
>> protocol StringCreatable 
>> {
>> 
>> static func createWithString(s: String) -> StaticSelf
>> 
>> }
>> 
>> 
>> extension NSURL: StringCreatable 
>> {
>> 
>> // can now conform conform because NSURL is fixed and matches the static
>> 
>> 
>> // type of the conforming construct. Subclasses need not re-implement
>> 
>> 
>> // NOTE: the return type can be declared as StaticSelf *or* as NSURL
>> 
>> 
>> //   they are interchangeable
>> 
>> 
>> static func createWithString(s: String) -> StaticSelf
>> { 
>> 
>> // ...
>> 
>> }
>> }
>> 
>> 
> 
> As I've noted before, I don't think this makes sense to encode in the 
> protocol. `Self` is already effectively invariant within a protocol. If a 
> protocol doesn't have the foresight to use StaticSelf, then you still have 
> the same problems retroactively conforming class hierarchies to the protocol. 
> Whether a conformance is inherited or not feels more natural as a property of 
> a conformance, not something that can be legislated a priori by a protocol 
> definition.
> 
> Something like StaticSelf might still be useful as shorthand within a class 
> definition with a long-winded name, though `StaticSelf` feels kind of long as 
> a shortcut to me.
> 
> -Joe
> ___
> 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