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

Matthew Johnson matthew at anandabits.com
Fri May 13 14:06:23 CDT 2016


> On May 13, 2016, at 1:11 PM, Nicola Salmoria via swift-evolution <swift-evolution at swift.org> wrote:
> 
> 
> 
> On Fri, May 13, 2016 at 12:55 PM, Vladimir.S <svabox at gmail.com <mailto:svabox at gmail.com>> 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<T: Fooable>(_ 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<Result: StringCreatable>(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<Result: StringCreatable where Result.ConformingType == Result>(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 at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160513/faddc0a1/attachment.html>


More information about the swift-evolution mailing list