> On Nov 2, 2016, at 8:32 AM, Paul Cantrell <[email protected]> wrote: > > >> On Oct 24, 2016, at 4:43 PM, Slava Pestov <[email protected]> wrote: >> >> >>> On Oct 24, 2016, at 8:12 AM, Paul Cantrell <[email protected]> wrote: >>> >>> >>>> On Oct 24, 2016, at 5:09 AM, Slava Pestov via swift-evolution >>>> <[email protected]> wrote: >>>> >>>> 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. >>> >>> FWIW, in almost all the situations where I’ve wanted to nest types inside >>> protocols and generic types, it’s only as a namespacing convenience. Most >>> often, it’s an enum type that’s used only by a single method, and having it >>> at the top of the module namespace adds clutter. >>> >>> Here’s a real life example pared down. I wish I could do this: >>> >>> public struct ResponseContentTransformer<InputContentType, >>> OutputContentType>: ResponseTransformer { >>> >>> public init(onInputTypeMismatch mismatchAction: InputTypeMismatchAction >>> = .error) { >>> ... >>> } >>> >>> public enum InputTypeMismatchAction { // Does not depend on generic >>> types above >>> case error >>> case skip >>> case skipIfOutputTypeMatches >>> } >>> >>> } >>> >>> InputTypeMismatchAction is tightly associated with >>> ResponseContentTransformer, and is confusing as a top-level type. >>> >>> What do you think about providing a “no captures” modifier for nested types >>> — like static inner classes in Java? Then Swift could provide the namespace >>> nesting I wish for this without having to resolve the trickier type capture >>> questions yet. >>> >>> Alternatively, what if (1) outer types aren’t capture unless they’re >>> referenced, and (2) nesting is only illegal if there’s a capture? Then my >>> code above would compile, as would this: >>> >>> public struct S<T> { >>> public enum Foo { >>> case yin >>> case yang >>> } >>> } >>> >>> …but this wouldn’t: >>> >>> public struct S<T> { >>> public enum Foo { >>> case yin(thing: T) // capture of T illegal (for now) >>> case yang >>> } >>> } >>> >>> Either of these approaches would allow hygienic namespacing now while >>> leaving the door open to outer type capture in the future. >> >> Yeah, this makes sense for a first cut at this feature. >> >> Slava > > Should I take a crack at writing up a proposal for this? Now? After ABI work > is done? (Probably the latter “OK if no captures” approach?) Eager to help; > don’t want to be in the way.
Just speaking for myself and not the whole team — I think you can submit the proposal at any time, we’re unlikely to get around to doing it, if you want to take a crack that would be great (again, with ‘no captures’ it’s “trivial”). Slava > > P > _______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
