> On Nov 2, 2016, at 8:32 AM, Paul Cantrell <[email protected]> wrote:
> 
> 
>> On Oct 24, 2016, at 4:43 PM, Slava Pestov <[email protected]> wrote:
>> 
>> 
>>> On Oct 24, 2016, at 8:12 AM, Paul Cantrell <[email protected]> wrote:
>>> 
>>> 
>>>> On Oct 24, 2016, at 5:09 AM, Slava Pestov via swift-evolution 
>>>> <[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
> 

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to