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@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@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@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

Reply via email to