+1 I really want protocols which can be namespaced inside structs/classes!
Thanks, Jon > On Jan 17, 2017, at 4:07 PM, Douglas Gregor via swift-evolution > <swift-evolution@swift.org> wrote: > > >> On Nov 5, 2016, at 2:44 AM, Karl via swift-evolution >> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >> >>> >>> On 2 Nov 2016, at 20:54, Slava Pestov <spes...@apple.com >>> <mailto:spes...@apple.com>> wrote: >>> >>>> >>>> On Nov 2, 2016, at 8:32 AM, Paul Cantrell <cantr...@pobox.com >>>> <mailto:cantr...@pobox.com>> wrote: >>>> >>>> >>>>> On Oct 24, 2016, at 4:43 PM, Slava Pestov <spes...@apple.com >>>>> <mailto:spes...@apple.com>> wrote: >>>>> >>>>> >>>>>> On Oct 24, 2016, at 8:12 AM, Paul Cantrell <cantr...@pobox.com >>>>>> <mailto:cantr...@pobox.com>> wrote: >>>>>> >>>>>> >>>>>>> On Oct 24, 2016, at 5:09 AM, Slava Pestov via swift-evolution >>>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> 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 >> >> >> Sorry, let this slip. Proposal sent - >> https://github.com/apple/swift-evolution/pull/552 >> <https://github.com/apple/swift-evolution/pull/552> > (Coming back to this after a very long time) > > One very high-level comment: one of your early examples is making the > Delegate of a view. Did you consider making this an Objective-C translation > rule as well, so that *Delegate and *DataSource protocols would be imported > as nested types within a class with the name signified by *, e.g., > > class UITableView { > @objc(UITableViewDataSource) > protocol DataSource { … } > > @objc(UITableViewDelegate) > protocol Delegate { … } > } > > - Doug > > > _______________________________________________ > 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