> On Jun 8, 2016, at 11:52 PM, Russ Bishop <[email protected]> wrote:
> 
>> 
>> On Jun 8, 2016, at 3:18 PM, Dave Abrahams via swift-evolution 
>> <[email protected] <mailto:[email protected]>> wrote:
>> 
>> Exactly.  But much simpler cases will also either have to trap at
>> runtime or be prohibited outright:
>> 
>>  func subscript_<C: Collection>(c: C, i: C.Index) -> C.Collection.Element {
>>    return c[i]
>>  }
>> 
>>  typealias IntCollection = Any<Collection where Element == Int>
>>  let c1: IntCollection = ...
>>  let c2: IntCollection = c1[3..<10]
>>  let c3: IntCollection = ...
>>  let c4: IntCollection = c1.reversed()
>> 
>>  // Note: the underlying index types are the same, and are supposed to
>>  // interoperate.  What do you do (work/trap/nocompile)?
>>  _ = subscript_(c1, c2.startIndex)
>> 
>>  // The underlying index types happen to be the same, and are not
>>  // supposed to interoperate.  What do you do (silently 
>> “work”/trap/nocompile)?
>>  _ = subscript_(c1, c3.startIndex)
>> 
>>  // The underlying index types are different.  What do you do 
>> (trap/nocompile)?
>>  _ = subscript_(c1, c4.startIndex)
>> 
>> -- 
>> Dave
> 
> Is it sufficient to say that unconstrained associated types cannot satisfy 
> generic constraints so subscript_ can’t be called with startIndex? 
> Presumably if you said Any<Collection where Element == Int, Index == Int> you 
> could then call subscript_.

Presumably, if a type was of existential type but all its associated types were 
constrained to concrete types and none contain Self requirements, you should be 
able to use it to satisfy a generic parameter. (Self requirements are still a 
problem. `Equatable` has no associated types, but you'd still run into problems 
using that existential in a generic context.)

Practically speaking, this wouldn't be too useful for most complex protocols. 
Swift 3's `Collection` defines at least `SubSequence`, `Indices`, `Index` (I 
think), and `Iterator`, all of which would have to be bound to meet this 
requirement. Then you get into recursive associated type constraints...

> 
> Not being a compiler expert another thought occurs to me: Can the type of an 
> existential/unconstrained associated type be an unique anonymous type in the 
> local scope? In this case c1.startIndex is of type a’; it cannot be stored in 
> a global, passed to another function, etc. It is only usable in the current 
> scope for interacting with c1. c2.startIndex would be of type b’, etc. This 
> is similar to how anonymous types work in C#. The issues with func<X>(a: X, 
> b: X) could in theory be solved the same way: require opening the existential 
> in the local scope and validating that the actual types are identical before 
> you can call func. 

Joe Groff thinks it's possible. I wrote something up along those lines here: 
https://github.com/austinzheng/swift-evolution/blob/az-existentials/proposals/XXXX-enhanced-existentials.md#associated-types-and-member-exposure
 
<https://github.com/austinzheng/swift-evolution/blob/az-existentials/proposals/XXXX-enhanced-existentials.md#associated-types-and-member-exposure>
> 
> In that sense you could say the types are really:
> 
> let c1: a’<IntCollection>
> let c2: b’<IntCollection>
> let c3: c’<IntCollection>
> let c4: d’<IntCollection>
> 
> // accepts responsibility for a and b being different concrete types at 
> runtime
> func doIt(a: IntCollection, b: IntCollection) { }
> 
> // caller must prove a & b are same concrete type
> func makeIt<C: Collection>(a: C, b: C) { }
> 
> 
> They are completely separate types until proven otherwise and you can’t go 
> passing them around unless the callee accepts responsibility for the dynamism 
> or you prove exactly which type you’re talking about.
> 
> (I freely admit this may be nonsensical or impossible to implement reasonably 
> in the compiler)
> 
> 
> Russ

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

Reply via email to