Lifting the “Self or associated type” Constraint on Swift Existentials
“PAT” is an acronym for Protocol with Associated Type. I coined the term in 2015 in a talk at the Swift functional programming conference that year.
That talk is a sort of a mirror of the confusion of Swift devs like myself at the time, who were excited about Swift protocols and your WWDC talk about protocol-oriented programming but also quite surprised by the limitations concerning associated types. I guessed at the motivations for this aspect of the language, relating it to other languages and to your talk. This was in the days before Swift was open-sourced, when we couldn’t just ask about these things.
I suspect many people, like me, are still a bit confused about the fundamental reason for these limitations.
[…]
Fwiw, I am sure the essential reason for the confusion then was that prototocols with associated types behaved almost exactly unlike protocols in objective-c, which was most everyone’s reference point.
I agree that the reference point of protocols in Objective-C was probably a source of confusion. However, I think the bigger source of confusion is that we have one thing called
protocol
that
- plays two distinct roles that overlap significantly in their capabilities
- can only support a fraction of its declared API in one of its roles
You can define the “existential type
P
” to be the most specific possible common supertype of all types conforming to the protocolP
. […]As for the fundamental reasons for this difference, it’s what I said in the talk: capturing an instance of type T as an existential type erases type information, and in particular, type relationships. If you work through a couple of examples with a protocol like […] you’ll see that the most specific common supertype of types conforming to
P
has no usable API. The compiler can’t provide a workinginit()
because it has no way to know which subtype to create.[…]
I loathe writing type-erasing wrappers as much as the next guy. But generalized existentials don’t eliminate the need to write them, nor (AFAICS) do they make it much easier to do so.
[…]
Nobody has proposed a set of features really targeted at the pain points you cite; that would be a really interesting exploration (I suspect the answer has at least as much to do with solving what I call “the API forwarding problem” as it does with existentials). Even if what is being proposed makes incremental progress toward solving those problems, though, I fear that in the specific place we arrive, having applied that increment, we’ll have done more harm than good as explained in my opening message.
Previously: Swift Protocols With Associated Types, Swift Protocols Wishlist, Patterns for Working With Associated Types, Swift Type Erasure.
See also: Type Erasers in Swift.