[swift-evolution] [swift-evolution-announce] [Review] SE-0089: Replace protocol<P1, P2> syntax with Any<P1, P2>
brent at architechies.com
Wed May 25 05:23:27 CDT 2016
> However, I believe this would have a significant advantage: it would clarify the distinction between an existential and a constraint. It would more clearly mark where you are taking on the abstraction overhead of an existential. It would also improve the non-existential type situation: in the short term, it would make it clearer where uses of associated type protocols like `Comparable` would not be permitted; in the long term, once we have type-erased existentials for those protocols, it would make it clearer when type erasure was in effect.
Sorry to self-reply, but I had some additional thoughts on this.
Swift's type system has a logical hierarchy of types. A type's supertypes include any protocols it conforms to, and then the protocols they conform to, ultimately rooted at Any. Additionally, a class's supertypes include its superclass, and then its superclass, and so on up to a root class, and then AnyObject, and finally Any once more. And of course, Any<…> lets you build composite types out of several protocols which fit into this framework: Any<Foo, Bar> is a subtype of both Foo and Bar and a supertype of any type which conforms to both Foo and Bar.
At an implementation level, however, this is only partially true. A class can be transformed into its superclass, all the way up to AnyObject, without any change in memory representation. But once you enter the world of protocols, everything changes. To cast to a protocol, you must place the instance in an existential, a different instance with a different memory layout. This can have significant performance consequences; for example, it's the reason you can't use `as` to convert an array of instances to an array of some protocol they all belong to.
Requiring the use of `Any<…>` to mark any existential would help reinforce this distinction. It would give users a better understanding of what their code was actually doing and why they might not be able to do things like make certain seemingly sensible casts.
(Although technically, this would seem to imply that AnyObject's future equivalent should *not* require an Any<>. Hmm.)
More information about the swift-evolution