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

Vladimir.S svabox at gmail.com
Thu May 19 11:36:33 CDT 2016


As I understand, the initial main idea of StaticSelf(actually it was #Self 
at the beginning) was just static replacement for the name of currently 
defined type(i.e. as placeholder for the name of type):

 >----------------------------<
     A further static identifier, #Self expands to static type of the code 
it appears within, completing the ways code may want to refer to the type 
it is declared in.

         #Self expands to the static type of the code it is declared 
within. In value types, this is always the same as Self. In reference 
types, it refers to the declaring type. #Self will offer a literal textual 
replacement just like #file, etc.
 >----------------------------<

Then it was transformed(in your [Draft]) to 'invariant type semantics in 
all contexts' with main target to use in '->StaticSelf' as requirement in 
protocols. Now, that proposal 'Will not be proposed'.

But what about the initial main idea?

So, I suggest to discuss if we want/need that #Self(or StaticSelf) in 
meaning '*placeholder for the type name where it is defined*'

I really think that such #Self can increase readability, clarity of code 
and could protect for some kind of errors(when you typed the wrong name of 
type or copy-pasted without change the name of the type).

I.e. as I understand the initial manin idea, the #Self could be used only 
inside class/struct/enum, not in protocols. So we can refer the same type 
not by concrete name, but by #Self(or StaticSelf or another chosen name)

What do you think?


On 18.05.2016 20:37, 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
>> <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>
>>>
>>> On May 14, 2016, at 12:55 AM, Nicola Salmoria via swift-evolution
>>> <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>>
>>> Matthew Johnson via swift-evolution <swift-evolution at ...> 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<T: Makable where T == T.RootMakable>(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<T: Makable where T == T.MadeType>(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<T: StringInitializable where T == T.Initialized>(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 at swift.org <mailto:swift-evolution at swift.org>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>


More information about the swift-evolution mailing list