> On Jan 4, 2016, at 11:43 AM, Douglas Gregor <dgre...@apple.com> wrote: > >> >> On Jan 4, 2016, at 6:24 AM, Matthew Johnson via swift-evolution >> <swift-evolution@swift.org <mailto: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)
Casting down makes sense and of course you could use the member after that. But why do we need a special cast operation “open” to do this? Is there a reason we couldn’t just cast down with the usual operators like we can with `Any`? > >> 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