> On 18 Jan 2017, at 01:07, Douglas Gregor <[email protected]> wrote:
> 
> 
>> On Nov 5, 2016, at 2:44 AM, Karl via swift-evolution 
>> <[email protected] <mailto:[email protected]>> wrote:
>> 
>>> 
>>> On 2 Nov 2016, at 20:54, Slava Pestov <[email protected] 
>>> <mailto:[email protected]>> wrote:
>>> 
>>>> 
>>>> On Nov 2, 2016, at 8:32 AM, Paul Cantrell <[email protected] 
>>>> <mailto:[email protected]>> wrote:
>>>> 
>>>> 
>>>>> On Oct 24, 2016, at 4:43 PM, Slava Pestov <[email protected] 
>>>>> <mailto:[email protected]>> wrote:
>>>>> 
>>>>> 
>>>>>> On Oct 24, 2016, at 8:12 AM, Paul Cantrell <[email protected] 
>>>>>> <mailto:[email protected]>> wrote:
>>>>>> 
>>>>>> 
>>>>>>> On Oct 24, 2016, at 5:09 AM, Slava Pestov via swift-evolution 
>>>>>>> <[email protected] <mailto:[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
>> 
>> 
>> 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
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to