> On Jan 4, 2016, at 6:24 AM, Matthew Johnson via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
>> 
>> On Jan 3, 2016, at 10:44 PM, Matthew Johnson <matt...@anandabits.com 
>> <mailto:matt...@anandabits.com>> wrote:
>> 
>> 
>>> On Jan 3, 2016, at 9:14 PM, Drew Crawford <d...@sealedabstract.com 
>>> <mailto:d...@sealedabstract.com>> wrote:
>>> 
>>> Sure, here's the start of the thread: 
>>> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151207/001856.html
>>>  
>>> <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151207/001856.html>
>> Thanks.  Joe was basically saying is that associated types would be 
>> automatically bound to the existential for their constraints, or Any if 
>> there are no constraints.  
>> 
>> He didn’t specifically mention anything about Self, but I suppose Self 
>> requirements could also be automatically bound to Any if the existential 
>> type doesn’t specify anything more specific, although I’m not sure I would 
>> like that behavior.
>> 
>> Self is what would apply in the case of:
>> 
>>> func compareTwo(first: Comparable, _ second: Comparable) -> Int {  // error!
>>>   if first < second {
>>>     return -1
>>>   }
>>>   //...
>>> }
>> If Self were automatically bound to Any what would this do?  Would it 
>> compile and invoke a `<` operator that takes two Any parameters?  That 
>> doesn’t seem to make sense to me.  It certainly wouldn’t guarantee you get 
>> the correct behavior if first and second were both Int for example.
> 
> I gave this some further thought last night and realized what would happen 
> here is pretty clear.  I hadn’t considered existentials where associated 
> types aren’t bound to concrete types before so it just took a few minutes to 
> work through.
> 
> Existentials reference a witness table pointing to an actual implementations 
> of the protocol requirements.  Actual implementations require parameters of 
> concrete types.  This means that you must know what that concrete type is and 
> supply a value of that type in order to actually call the member.  The 
> implication of this is that members which require parameters of an associated 
> type that is not bound to a concrete type will not be available on that 
> existential.  

There is a concrete type, which is known dynamically to the existential value, 
but you would need a way to name that type to (e.g.) cast down to it before you 
could use the member. That’s why the open..as operation I mentioned allows one 
to use these members: it gives a way to name the type. It actually helps to 
think of any operation on existentials as implicitly using open..as, because it 
makes the semantics far more explicit. (The compiler does this internally as 
well)

> In this example, `<` requires two arguments of type Self.  However, the 
> `Comparable` existential, if allowed, would have Self bound to `Any`, not a 
> concrete type.  Therefore `<` would not be available and you would receive a 
> compiler error on that line.  It would be different than the current error 
> and on a different line of code but it would still fail to compile.
> 
> With return types, you do not necessarily need to know the concrete type 
> returned by the implementation.  Swift could theoretically box the result 
> itself into an existential and return that to the caller.  I do not know 
> whether this is the actual design that will be implemented or not.

It’s a reasonable direction that we’ve discussed in passing but never committed 
to.

        - Doug

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

Reply via email to