Lifting the "Self or associated type" constraint on existentials

Maybe it's just my overly-literal brain, but that statement confuses me. I didn't claim that the proposal made any of the three items listed worse, nor were those three items “points” I was trying to make. I suggested three things that should be made explicit. If what you're really saying is that today those things are implicit and they would stay that way under the proposal, then we agree.

I also claim keeping those things implicit while opening up the space of existential usage would have some negative effects, which I'm not going to repeat here. Further, if we were to talk about my items as points that could possibly be made worse by a language change, then in fact your proposal would make #3 worse, by expanding the set of a protocol's APIs that an available existential could not support.

Right now, no existential conforms to its protocol (discounting AnyObject or some @objc protocols), and that doesn't change. To be resilient, it will have to be opt-in when we do support it, addressing #1. #2 seems like the same point as #1 to me; maybe you can clarify the distinction to me.

#2 and #1 are only the same if you consider conformance to P to be part of the declared API of P itself. To me that isn't obviously the case given our syntax. I'd expect to see that spelled something like:

protocol P : Self {}

But I would be happy to consider a design that didn't make a distinction between #1 and #2, since #3 and #1 together cover the entire space of possibilities.

As for #3, even with the existing restriction, thanks to protocol extensions, it's already the case that an existential's API can diverge from the conforming type's.

Yes, and I claim we should take that possibility away or force it to be explicit where that happens, even if it means breaking source.

In the fullness of time, when we support opening existentials, I also think that distinction will disappear—fundamentally, the only operation an existential supports is opening it and manipulating the underlying dynamic value; once the value is opened, the entire protocol API is available relative to the dynamic type of that value. Like I said, I'm all for making existentials more explicit.

Except that I'm sure you are not proposing to require explicitly opening every existential before using any of its APIs. The basic problems remain: some operations will be available implicitly, and others will only be available when the existential is explicitly opened, and exactly which will be based on obscure rules of type soundness. When you reach a point where an existential must be opened, your code may not even be structured so that the type to open the existential as is available to you, because the language has provided a way to code yourself into a very attractive, but deep, and almost invisible, hole.

1 Like