I was reading through the Hacklang docs on Collections, and came across this curious definition [paraphrased slightly]:

interface KeyedIterable<Tk, Tv> ...
interface ConstVector<+Tv> implements KeyedIterable<int, Tv>  ...

Of course, KeyedIterable must be read-only with respect to Tv, and indeed it is since its methods cannot modify its type. It could be specified to be covariant on at least Tv, but isn't.

I was wondering what impetus there could be to do this?

Edit: I read the definition wrong, KeyedIterable is actually defined as KeyedIterable<Tk, +Tv>, so this definition makes perfect sense. I'm just realizing now that it's not so much "should or should not", but rather "this is never possible".

  • 2
    To do what? Create an interface definition that, even though the designers could have specified to be covariant on tv, they didn't? Apr 3, 2016 at 5:12
  • @RobertHarvey I think that's my confusion? I fail to see what the design incentive is to not make the parent class covariant on Tv, here or ever.
    – concat
    Apr 3, 2016 at 5:30

1 Answer 1


Suppose interface KeyedIterable implements a method Combine that takes another KeyedIterable instance and merges it with itself. That would result in a mixed collection of different types. Then there may be a method GetTotal that adds all the values in the collection and returns the result. That could blow up, the plus may be overloaded for the subtype and be incompatible with the add of the base type.

This explanation appears to be appreciated: https://stackoverflow.com/questions/663254/why-doesnt-the-example-compile-aka-how-does-co-contra-and-in-variance-w/674090#674090

  • No, this is a bad example. He explicitly stated that KeyedIterable is read-only. This is just a bunch of hypotheticals that would basically just amount to "Because the interface design is shit", instead of any compelling reason.
    – DeadMG
    Apr 3, 2016 at 10:21
  • Yes, I forgot about that part. Here's another thought. Isn't the KeyedIterable Tv implicitly covariant since it follows the ConstVector Tv? After all, there will be only one Tv at a time (per class declaration). You cannot have one value type for ConstVector and another for KeyedIterable. So a + or - with the second Tv would be meaningless. Apr 3, 2016 at 15:51
  • Though in this particular case, another class ConstMap<+Tk, +Tv> implements KeyedIterable as well. My question actually comes from a specific use case: it's proven valuable to be able to return either Maps or Vectors, but annoyingly the invariance of Tk in KeyedIterable makes this impossible.
    – concat
    Apr 3, 2016 at 16:25
  • I was wrong here too: I had assumed that ConstMap was covariant on Tk like the rest of the Const family (outside of ConstMapAccess and ConstIndexAccess which are consequently why ConstMap is invariant on Tk). I opened and subsequently closed a GitHub issue covering this.
    – concat
    May 17, 2016 at 20:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.