Generic Covariance to improve API Usage

It's a useful feature but also really really hard.

  • For value types with a covariant generic parameter, the upcast might involve a representation change (consider going from Optional<Int> to Optional<Any>).

  • For reference types with a covariant generic parameter, you don't even have a chance to change the representation (since you need to preserve reference semantics), which rules out certain kinds of covariance.

  • For non-ObjC generic reference types, the generic arguments are included in the runtime type, which means the same instance can't be both a Box<Dog> and a Box<Animal> at the same time. One of them is always the "real" type.

  • If you're implementing something like Array, you have to be doubly careful about having a reference type backing your value type. Make sure not to put a Cat in your Animal array storage if it's also backing an array of Dogs!

  • And none of that is talking about the compiler side of it, expanding the limited support that's there for four specific types (Array, Set, Dictionary, and Optional) to something generalizable.

So it's theoretically possible to add to Swift for value types*, it'd be a big undertaking on the compiler side, and probably not so straightforward to write a type for it even once the feature is fully designed.

* and (ironically) for Objective-C classes, which do not store the generic parameters at runtime.

15 Likes