// Can represent a first-class function in Java as an object // with a single "apply" method. interface Fun { public Object apply (Object x); } // Representing the linear function ax + b as an object // with instance variables a and b: class Linear implements Fun { private int a, b; // integer instance variables public Linear (int a, int b) { this.a = a; this.b = b; } public Object apply (Object x) { // Must deal with hassle of unwrapping integers from wrapping // integers into instances of the integer wrapper class. Yuck! // Doesn't it make you feel like you need to take a shower? return new Integer (a * ((Integer) x).intValue() + b); } } public class Mapper { // Handy way to abbreviate "ObjectList." as "OL." public static ObjectList OL; public static ObjectList map (Fun f, ObjectList L) { if (OL.isEmpty(L)) { return L; } else { return OL.prepend(f.apply(OL.head(L)), map(f, OL.tail(L))); } } // Parse a string representation of an integer list into a list of IntegerObjects. public static ObjectList parseIntList (String s) { return map (// Example of "anonymous inner class" new Fun() { public Object apply (Object x) { return new Integer ((String) x); } }, OL.fromString(s)); // fromList returns a list of strings } public static void main (String [] args) { if (args[0].equals("linear1")) { int a = Integer.parseInt(args[1]); int b = Integer.parseInt(args[2]); ObjectList L = parseIntList(args[3]); System.out.println(map(new Linear(a,b), L)); } else if (args[0].equals("linear2")) { final int a = Integer.parseInt(args[1]); // Java requires these be be final final int b = Integer.parseInt(args[2]); // in order to close over them // Create an anonymous linear function Fun f = new Fun() { public Object apply (Object x) { return new Integer (a * ((Integer) x).intValue() + b); } }; ObjectList L = parseIntList(args[3]); System.out.println(map(f, L)); } else { System.out.println("unrecognized option"); } } /* Examples of running the above [fturbak@jaguar java] java Mapper linear1 2 3 [1,2,3,4,5] [5,7,9,11,13] [fturbak@jaguar java] java Mapper linear2 2 3 [1,2,3,4,5] [5,7,9,11,13] */ }