Hacker News new | ask | show | jobs
by munificent 3440 days ago
It's only meaningful if you are using a language that has static types, subtyping, and generics. That covers Java, C#, and Dart, but omits Ruby (no static types), SML (no subtyping), and Go (no generics), for example.

If you are a language where it matters, it comes in handy, even though you usually aren't aware of it. You probably already have a correct intuition of it without realizing it.

Say you have a class like:

    class Enclosure<T> {
      void cage(T item) { ... }
    }
And assume some sort of class hierarchy like "Mammal is a subclass of Animal". If you have a method like:

   putKittyInCage(Enclosure<Mammal> enclosure, Mammal kitty) {
     enclosure.cage(kitty);
   }
Is this OK?

   putKittyInCage(new Enclosure<Animal>(), kitty);
The method expects an Enclosure<Mammal> and we're giving it an Enclosure<Animal>. Is that allowed? You probably intuitively see that it should be — an Enclosure<Animal> can hold any kind of animal and mammals are all animals. Your intuition is right.

"Contravariance" is the term to describe precisely what that intuition represents.