[swift-evolution] namespacing protocols to other types

Karl Wagner razielim at gmail.com
Wed Dec 27 12:53:27 CST 2017


Yeah I wrote that proposal. I eventually stripped it down to just disallow all capturing, but it was still not selected by the core team for review ¯\_(ツ)_/¯

As for capturing semantics, once you start working through use-cases, it’s becomes clear that it's going to require generalised existentials. Otherwise, how would you use a Generic<T>.P?

struct Generic<T> {
    protocol P { func f() -> T }

    var object: P // uh-oh! ‘Generic protocol can only be used as a generic parameter constraint'
}

So, you would need to add a generic parameter to actually use P from within Generic<T>, which of course limits you to a single concrete type of P:

struct Generic<T, TypeOfP> where TypeOfP: Self.P {      // Could this even work? What if P captures TypeOfP?
    protocol P { /* … */ }
    var object: TypeOfP
}

Which is just yucky.

Ideally, the type of ‘object’ should be ‘Any<P where P.T == T>’, to express that it can be any conforming type with the appropriate constraints. You wouldn’t need to write that all out; we could infer that capturing is equivalent to a same-type constraint (or perhaps one of these “generalised supertype constraints” that were pitched recently). But we can’t express those kinds of existentials everywhere in the type-system today, so most examples of capturing fall down pretty quickly.

- Karl

> On 25. Dec 2017, at 03:56, Slava Pestov via swift-evolution <swift-evolution at swift.org> wrote:
> 
> There was a proposal to allow protocols to be nested inside types at one point but it didn’t move forward.
> 
> Basically, if the outer type is a non-generic class, struct or enum, there’s no conceptual difficulty at all.
> 
> If the outer type is a generic type or another protocol, you have a problem where the inner protocol can reference generic parameters or associated types of the outer type. This would either have to be banned, or we would need to come up with coherent semantics for it:
> 
> struct Generic<T> {
>  protocol P {
>    func f() -> T
>  }
> }
> 
> struct Conforms : Generic<Int>.P {
>  func f() -> Int { … } // Like this?
> }
> 
> let c = Conforms()
> c is Generic<String>.P // is this false? Ie, are Generic<Int>.P and Generic<String>.P different protocols?
> 
> Slava
> 
>> On Dec 24, 2017, at 6:53 PM, Kelvin Ma via swift-evolution <swift-evolution at swift.org> wrote:
>> 
>> is there a reason why it’s not allowed to nest a protocol declaration inside another type?
>> _______________________________________________
>> 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

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


More information about the swift-evolution mailing list