I left some review comments here:

https://github.com/apple/swift-evolution/commit/ff654e4

Slava

> On Jan 18, 2017, at 12:17 AM, Karl Wagner <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

Reply via email to