[swift-evolution] [Draft] Introducing StaticSelf, an Invariant Self
Thorsten Seitz
tseitz42 at icloud.com
Thu May 19 00:01:12 CDT 2016
Geeat solution! Thanks to Nicola for posting it!
> Am 14.05.2016 um 16:35 schrieb Matthew Johnson via swift-evolution <swift-evolution at swift.org>:
>
>
>> On May 14, 2016, at 12:55 AM, Nicola Salmoria via swift-evolution <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.
+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 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