[swift-evolution] subprotocol as type when super protocol has an associated type
Anders
hello at andersio.co
Sat Jun 24 17:24:34 CDT 2017
Whether the protocol inherits from another protocols does not matter. As
long as the protocol requirements include associated types, it would not
be possible to be used as existentials (for now).
Moreover, even if you use the "subprotocols" inside a generic
environment that constrains `A`, it does not change how the symbol `B`
and `C` mean inside that context. They are still unbound protocols.
The feature you called for is generalized existentials. It is on the
Generic Manifesto and had a few long discussion threads on the list
before. Apparently, it is out of scope for Swift 4, and whether it is in
scope of Swift 5 remains to be seen.
By the way, for your code snippet, apparently you may simply add
"doSomething" overloads for `P: B` and `P: C`. The compiler will pick
the most specific variant for you at compile time. Deferring to runtime
with existentials is not necessarily the only option.
On Sun, Jun 25, 2017, at 01:50 AM, Benjamin Spratling via swift-evolution wrote:> I’m running into trouble using protocols as types when they have an
> associated type. I understand the restriction of using a protocol
> with an associated type only as a generic constraint, since our down-
> casting syntax has no way of checking the associated types. However,
> if I’m considering whether an instance conforms to a sub protocol,
> which introduces no additional associated types itself, when the
> instance is already known to conform to the super-protocol which
> introduces the associated type, I believe such behavior is well-
> defined, and should be supported. So, I’m asking for help to put
> together a proposal to get this added.>
> Here’s an example:
> 3 protocols, one base Protocol which declares an associated type.
> And 2 sub-protocols.
>
> protocol A {
> associatedType V
> }
>
> protocol B : A {
> func someFunction<V>(V?)->String
> }
>
> protocol C : B {
> func someOtherFunction<V>()->V?
> }
>
> Note that the sub protocols do not add additional associated types.
>
> When I want to use these protocols, using the base protocol as a
> generic constraint works fine.>
> class M {
> func doSomething<P, V>(a:P, completion:@escaping(V?)->()) where P : A,
> V==P.V {> if let c = a as? C {
> c.someOtherFunction(…)
> … more code
> } else if let b = a as? B {
> b.someFunction(…)
> … more code
> }
> }
> }
>
> However, when I try to check whether the instance conforms to either
> of the sub-protocols, I get an error, saying protocols with associated
> types can only be used as generic constraints.>
> I believe that in this case, since the sub-protocols do not add any
> additional associated types, this code should be well-defined, and
> compilable.>
> _________________________________________________
> 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/20170625/ad390ed5/attachment.html>
More information about the swift-evolution
mailing list