> On Oct 24, 2016, at 4:43 PM, Slava Pestov <spes...@apple.com> wrote:
> 
> 
>> On Oct 24, 2016, at 8:12 AM, Paul Cantrell <cantr...@pobox.com> wrote:
>> 
>> 
>>> On Oct 24, 2016, at 5:09 AM, Slava Pestov via swift-evolution 
>>> <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.

P

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to