GJ: A Generic Java
by Philip Wadler


Listing One
interface List {
  public void add (Object x);
  public Iterator iterator ();
}
interface Iterator {
  public Object next ();
  public boolean hasNext ();
}
class LinkedList implements List { ... }
class Test {
  public static void main (String[] args) {

    // byte list
    List xs = new LinkedList();
    xs.add(new Byte(0)); xs.add(new Byte(1));
    Byte x = (Byte)xs.iterator().next();

    // string list
    List ys = new LinkedList();
    ys.add("zero"); ys.add("one");
    String y = (String)ys.iterator().next();

    // string list list
    List zss = new LinkedList();
    zss.add(ys);
    String z = (String)((List)zss.iterator().next()).iterator().next();

    // string list treated as byte list
    Byte w = (Byte)ys.iterator().next();  // run-time exception
  }
}

Listing Two
interface List<A> {
  public void add(A x);
  public Iterator<A> iterator();
}
interface Iterator<A> {
  public A next();
  public boolean hasNext();
}
class LinkedList<A> implements List<A> { ... }
class Test {
  public static void main (String[] args) {

    // byte list
    List<Byte> xs = new LinkedList<Byte>();
    xs.add(new Byte(0)); xs.add(new Byte(1));
    Byte x = xs.iterator().next();

    // string list
    List<String> ys = new LinkedList<String>();
    ys.add("zero"); ys.add("one");
    String y = ys.iterator().next();

    // string list list
    List<List<String>> zss = new LinkedList<List<String>>();
    zss.add(ys);
    String z = zss.iterator().next().iterator().next();

    // string list treated as byte list
    Byte w = ys.iterator().next();  // compile-time error
  }
}

Listing Three
interface Comparable {
  public int compareTo (Object that);
}
class Byte implements Comparable {
  private byte value;
  public Byte (byte value) { this.value = value; }
  public byte byteValue () { return value; }
  public int compareTo (Byte that) {
    return this.value - that.value;
  }
  // bridge
  public int compareTo (Object that) {
    return this.compareTo((Byte)that);
  }
}
class Lists {
  public static Comparable max (List xs) {
    Iterator xi = xs.iterator();
    Comparable w = (Comparable)xi.next();
    while (xi.hasNext()) {
      Comparable x = (Comparable)xi.next();
      if (w.compareTo(x) < 0) w = x;
    }
    return w;
  }
}
class Test {
  public static void main (String[] args) {

    // byte list
    List xs = new LinkedList();
    xs.add(new Byte(0)); xs.add(new Byte(1));
    Byte x = (Byte)Lists.max(xs);

    // boolean list
    List ys = new LinkedList();
    ys.add(new Boolean(false)); ys.add(new Boolean(true));
    Boolean y = (Boolean)Lists.max(ys);  // run-time exception
  }
}


Listing Four
interface Comparable<A> {
  public int compareTo (A that);
}
class Byte implements Comparable<Byte> {
  private byte value;
  public Byte (byte value) { this.value = value; }
  public byte byteValue () { return value; }
  public int compareTo (Byte that) {
    return this.value - that.value;
  }
}
class Lists {
  public static <A implements Comparable<A>> A max (List<A> xs) {
    Iterator<A> xi = xs.iterator();
    A w = xi.next();
    while (xi.hasNext()) {
      A x = xi.next();
      if (w.compareTo(x) < 0) w = x;
    }
    return w;
  }
}
class Test {
  public static void main (String[] args) {

    // byte collection
    LinkedList<Byte> xs = new LinkedList<Byte>();
    xs.add(new Byte(0)); xs.add(new Byte(1));
    Byte x = Collections.max(xs);

    // boolean collection
    LinkedList<Boolean> ys = new LinkedList<Boolean>();
    ys.add(new Boolean(false)); ys.add(new Boolean(true));
    Boolean y = Collections.max(ys);  // compile-time error
  }
}

Listing Five
class LinkedList<A> implements Collection<A> {
  public LinkedList ();
  public void add (A elt);
  public Iterator<A> iterator ();
}




3


