next up previous
Next: Higher-order functions Up: A slice of Pizza: Previous: Introduction

Parametric polymorphism

Reusable components act on many types. In Java, this is often supported by operating on the class Object, but this requires a great deal of casting, which can be awkward and error prone. To illustrate, here is a sorter in Java, followed by the same program in Pizza.

In the Java program, the marked line will fail at run time, because a comparator for integers is used with strings. In the corresponding Pizza program, the same line will cause an error at compile time (and so the whole line itself is commented out).

Also, note that in the Java program, for sorting purposes one must use an array of Integer not an array of int, since Integer (but not int) is a subclass of Object. Pizza can work with the int type directly. (It does this by using a special representation for arrays of polymorphic type, and by automatically packing an int as an Integer when an Object is expected.)





Example 2.1 Sort in Java.

abstract class Ord {
  public abstract boolean leq (Object x, Object y);
}

class OrdInteger extends Ord {
  public boolean leq (Object x, Object y) {
    return ((Integer)x).intValue() <= ((Integer)y).intValue();
  }
}

class OrdString extends Ord {
  public boolean leq (Object x, Object y) {
    return (((String)x).compareTo((String)y) <= 0);
  }
}

class Sort {
  static void sort (Ord p, Object[] a) {
    for (int i = 0; i < a.length; i++) {
      for (int j = i+1; j < a.length; j++) {
        if (!p.leq(a[i],a[j])) {
          Object t=a[i]; a[i]=a[j]; a[j]=t;
  } } } }
  public static void main(String[] args) {
    Integer[] a = { new Integer(2), new Integer(1) };
    sort(new OrdInteger(), a);
    String[] b = {"data", "ditto", "dada"};
    sort(new OrdString(), b);
    sort(new OrdInteger(), b);  /* RUN-TIME ERROR */
  }
}












Example 2.2 Sort in Pizza

abstract class Ord<T> {
  public abstract boolean leq (T x, T y);
}

class OrdInteger extends Ord<int> {
  public boolean leq (int x, int y) {
    return x <= y;
  }
}

class OrdString extends Ord<String> {
  public boolean leq (String x, String y) {
    return x.compareTo(y) <= 0;
  }
}

class Sort {
  static <T> void sort (Ord<T> p, T[] a) {
    for (int i = 0; i < a.length; i++) {
      for (int j = i+1; j < a.length; j++) {
        if (!p.leq(a[i],a[j])) {
          T t=a[i]; a[i]=a[j]; a[j]=t;
  } } } }
  public static void main(String[] args) {
    int[] a = {2, 1};
    sort(new OrdInteger(), a);
    String[] b = {"data", "ditto", "dada"};
    sort(new OrdString(), b);
    /* sort(new OrdInteger(), b);  COMPILE-TIME ERROR */
  }
}








Philip Wadler