I've really come to appreciate OCaml's notion of generics. It doesn't have subtyping, so e.g. you have an `int list` or an arbitrary `'a list`, but nothing inbetween. As soon as you add constraints like Java's `List<? as Foo>` it become incredibly hard to produce good errors.