Generics
(the hard way)
Problem #1. Arrays are
covariant
Sub :> Super -> Sub[] :> Super[]
Generics are invariant
Object[] arr = new Long[1];
arr[0] = "Not a cool kid, I don't fit in"; // <-- Throws
ArrayStoreException at runtime
Problem #2. Arrays are reified,
generics - by erasure
Illegal:
new List<E>[]
new List<String>[]
new E[]
// Why generic array creation is illegal - won't compile!
List<String>[] stringLists = new List<String>[1]; // (1)
List<Integer> intList = Arrays.asList(42); // (2)
Object[] objects = stringLists; // (3)
objects[0] = intList; // (4)
String s = stringLists[0].get(0); // (5)
Don’t mix arrays and generics
We need power!!!
public class Stack<E> {
public Stack();
public void push(E e);
public E pop();
public boolean isEmpty();
}
public void pushAll(Iterable<E> src) {
for (E e : src)
push(e);
}
Example
Stack<Number> numberStack = new Stack<Number>();
Iterable<Integer> integers = ... ;
numberStack.pushAll(integers); // Nooooooo
Push All
public void pushAll(Iterable<? extends E> src) {
for (E e : src)
push(e);
}
Push with some magic
// popAll method without wildcard type - deficient!
public void popAll(Collection<E> dst) {
while (!isEmpty())
dst.add(pop());
}
Stack<Number> numberStack = new Stack<Number>();
Collection<Object> objects = ... ;
numberStack.popAll(objects); // Noooooooooo
Pop All
public void popAll(Collection<? super E> dst) {
while (!isEmpty())
dst.add(pop());
}
Pop with pure magic
Just PECS everywhere
producer-extends, consumer-super
Max, come on ...
Object max(List src) {
// ...
}
Max, are you kidding me
public <T extends Comparable<? super T>> T max( List<? extends T> list) {
// ...
}
Swift Magic
protocol Foo {
typealias Key
typealias Element
}
protocol Bar {
typealias RawGeneratorType
}
func example<T : Foo, U, V where V : Foo, V : Bar, T.Key ==
V.RawGeneratorType, U == V.Element>
(arg1: T, arg2: U, arg3: V) -> U {
// ...
}
Swift insane Magic
// Methods in this extension are only available to Arrays whose elements are
// both hashable and comparable.
extension Array where Element : Hashable, Element : Comparable {
// ...
}

Generics. PECS

  • 1.
  • 2.
    Problem #1. Arraysare covariant Sub :> Super -> Sub[] :> Super[] Generics are invariant
  • 3.
    Object[] arr =new Long[1]; arr[0] = "Not a cool kid, I don't fit in"; // <-- Throws ArrayStoreException at runtime
  • 4.
    Problem #2. Arraysare reified, generics - by erasure Illegal: new List<E>[] new List<String>[] new E[]
  • 5.
    // Why genericarray creation is illegal - won't compile! List<String>[] stringLists = new List<String>[1]; // (1) List<Integer> intList = Arrays.asList(42); // (2) Object[] objects = stringLists; // (3) objects[0] = intList; // (4) String s = stringLists[0].get(0); // (5)
  • 6.
    Don’t mix arraysand generics
  • 7.
  • 8.
    public class Stack<E>{ public Stack(); public void push(E e); public E pop(); public boolean isEmpty(); } public void pushAll(Iterable<E> src) { for (E e : src) push(e); } Example
  • 9.
    Stack<Number> numberStack =new Stack<Number>(); Iterable<Integer> integers = ... ; numberStack.pushAll(integers); // Nooooooo Push All
  • 10.
    public void pushAll(Iterable<?extends E> src) { for (E e : src) push(e); } Push with some magic
  • 11.
    // popAll methodwithout wildcard type - deficient! public void popAll(Collection<E> dst) { while (!isEmpty()) dst.add(pop()); } Stack<Number> numberStack = new Stack<Number>(); Collection<Object> objects = ... ; numberStack.popAll(objects); // Noooooooooo Pop All
  • 12.
    public void popAll(Collection<?super E> dst) { while (!isEmpty()) dst.add(pop()); } Pop with pure magic
  • 13.
  • 14.
    Max, come on... Object max(List src) { // ... }
  • 15.
    Max, are youkidding me public <T extends Comparable<? super T>> T max( List<? extends T> list) { // ... }
  • 16.
    Swift Magic protocol Foo{ typealias Key typealias Element } protocol Bar { typealias RawGeneratorType } func example<T : Foo, U, V where V : Foo, V : Bar, T.Key == V.RawGeneratorType, U == V.Element> (arg1: T, arg2: U, arg3: V) -> U { // ... }
  • 17.
    Swift insane Magic //Methods in this extension are only available to Arrays whose elements are // both hashable and comparable. extension Array where Element : Hashable, Element : Comparable { // ... }