Nested types in protocols (and nesting protocols in types)

That’s also on the line: [https://github.com/apple/swift/blob/611fc78d28a5da97dd1bea40761b913b1077aef5/docs/GenericsManifesto.md#nested-generics](https://github.com/apple/swift/blob/611fc78d28a5da97dd1bea40761b913b1077aef5/docs/GenericsManifesto.md#nested-generics)

--
Adrian Zubarev
Sent with Airmail

Am 17. Oktober 2016 um 20:26:47, T.J. Usiyan (griotspeak@gmail.com <mailto:griotspeak@gmail.com>) schrieb:

I want this feature. Both class in protocol and protocol in class could clean up many relationships but I think that a blocking concern is "How does this interact with generics?" Nesting types in generic types is already disallowed and how different is this feature from that?

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

And even partially implemented, behind the flag “-enable-experimental-nested-generic-types”. I don’t know what’s missing from it, but it seemed to work in some simple cases last time I tried.

This flag implements nesting non-protocol generic types inside other non-protocol generic types, except for some bugs I need to fix before I can just enable this all by default.

However protocols nested inside types and types nested inside protocols is still not supported, because protocols introduce a separate series of issues involving associated types and the ’Self’ type.

The hard part of getting nested generics right is what to do if a nested type ‘captures’ generic parameters of the outer type. For non-protocol types, the behavior here is pretty straightforward.

If we allow protocols to be nested inside other types, we have to decide what to do if the protocol ‘closes over’ generic parameters of the outer type. For example,

struct A<T> {
  protocol P {
    func requirement() -> T
  }
}

Presumably A<Int>.P and A<String>.P are distinct types, and A.P has a hidden associated type corresponding to the type parameter ’T’?

The other case is problematic too — the nested type might refer to an associated type of the outer protocol:

protocol P {
  associatedtype A

  struct T {
    var value: A
  }
}

Now writing P.T does not make sense, for the same reason that we cannot form an existential of type P.A. We could prohibit references to outer associated types of this form, or we could figure out some way to give it a meaning. If C is a concrete type conforming to P, then certainly C.T makes sense, for instance. Internally, the nested type A.T could have a hidden ‘Self’ generic type parameter, so that writing C.T is really the same as P.T<C>.

Protocols nested inside protocols also have the same issue.

Also note that even with the experimental flag, generic types nested inside generic *functions* are not supported either. Here, again, the difficulty is with captured generic parameters. The semantics are clear but the implementation needs some work.

Slava

···

On Oct 17, 2016, at 11:35 AM, Karl via swift-evolution <swift-evolution@swift.org> wrote:

On 17 Oct 2016, at 20:31, Adrian Zubarev via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

- Karl
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution