Thursday, November 29, 2018

Lifting the “Self or associated type” Constraint on Swift Existentials

Alexis Gallagher (tweet):

“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.

Dave Abrahams:

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 protocol P. […]

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 working init() 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.

Comments RSS · Twitter

Leave a Comment