Consider this legacy code:public interface IPersistentCollection {    IPersistentCollection cons(Object o);}Genericized in Java, it could become something like this:public interface IPersistentCollection<T> {    IPersistentCollection<T> cons(T o);}Clearly adding a new item to a mutable Java collection shouldn't change the type of the existing collection.  But unlike the Java collections, cons() returns a completely new, immutable collection, leaving the old collection unchanged, opening the possibility that it could meaningfully take on a different type than the original collection had.Obviously, you should be able to cons an object of type Ford to a collection of Cars and get a collection of Cars back (covariance).  I think this is covered by the above generic example.If Car and Train both extended a Vehicle class, it would be handy to be able to cons a Train to a collection of Cars and get a collection of Vehicles back (contravariance).  How would I even write that?  I thought by declaring new bounded type variables, S and E for Vehicle and Train in this example:// Illegal because of <S super T><S super T, E extends S> IPersistentCollection<S> cons(E o);// Simpler, but still Illegal because java disallows <S super T><S super T> IPersistentCollection<S> cons(S o);If we want to assume that the programmer knows what they are doing, you should be allowed to cons something totally unrelated to a collection and get a collection of Objects back.  I think this is the extreme case of contravariance, but I'm not sure there is even a name for it (Dynamic Language maybe?).I think that if #2 were legal, it would cover cases #1 and #3.My questions are:A. To what degree is it possible to do #2 in Java?B. Is #2 possible/easier in other languages?  Scala?  Haskell? ML?C. In theory, a type system that preferred the most specific version of S in example 2 could handle a definition like this.  What book can I read about type systems without a PHD in math?  Is Types and Programming Languages by Pierce the best place to start?Sample code would be appreciated.  If I'm using terms like covariance and contravariance incorrectly, I would appreciate being politely corrected.
Parameterized Java Types (Generics)
java;type systems;generics;parameters;type safety