What are the differences between protocols that do or don't have Self/PAT requirements?

I know that protocols can be used to constrain a generic parameter type. And a protocol can be used as a variable's type, a placeholder which can hold any value of any conforming type. (And for a var, different actual types at different times.) But a protocol with Self/associatedtype requirements cannot be used as a variable, only for a generic constraint. I understand the reason why is that types sharing a SoAT protocol have the same interface in shape, but not the same interface in the specific inner types used. Meanwhile, types sharing a non-SoAT protocol have the same interface in shape and inner types.

What other uses can you use a non-SoAT protocol type for? And other uses for SoAT protocol types?

There isn't a fundamental difference; this is an implementation limitation. There was a lot of discussion about this topic in this thread:

1 Like

There's still a distinction in what you can do with members that reference Self or an associated type, though…

It's a bit subtler than that, because it isn't the Self or associated types in and of themselves that create those restrictions, but specifically the combination of using protocols as types with type-erased types in argument position.

3 Likes

I feel like that's a pretty misleading statement about generics. Dave Abrahams put it this way in a past talk: "generics preserve types; existentials erase them". If you care about types, you probably want generics.

2 Likes

Sorry about that, I got the details backwards by mistake :confused: