I would use this pretty much constantly!  I thought it was going to be in Swift 
4, and have really been missing it…


> On Nov 26, 2017, at 8:51 AM, Adrian Zubarev via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
> 
> What happened to this? Should we revive this talk? I’d love to finally be 
> able to nest protocols in Swift 5 and clean up my code.
> 
> Am 18. Januar 2017 um 09:48:20, Slava Pestov via swift-evolution 
> (swift-evolution@swift.org <mailto:swift-evolution@swift.org>) schrieb:
> 
>> I left some review comments here:
>> 
>> https://github.com/apple/swift-evolution/commit/ff654e4 
>> <https://github.com/apple/swift-evolution/commit/ff654e4>
>> 
>> Slava
>> 
>>> On Jan 18, 2017, at 12:17 AM, Karl Wagner <razie...@gmail.com 
>>> <mailto:razie...@gmail.com>> wrote:
>>> 
>>> 
>>>> On 18 Jan 2017, at 01:07, Douglas Gregor <dgre...@apple.com 
>>>> <mailto:dgre...@apple.com>> 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
>>>> 
>>>> 
>>> 
>>> Yes, and platform SDK changes are mentioned under “Source Compatibility”.
>>> 
>>> I’ve removed the standard library stuff from it now, that can happen later. 
>>> Would we be able to get the ball rolling on getting it reviewed?
>>> 
>>> Thanks
>>> 
>>> - Karl
>>> 
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> <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