Friday, December 28, 2007

Advanced Features

Advanced features

A function type can be used as type parameter:

  public static void main(String[] args) {
    List<{ int, int => int }> operations = 
      new ArrayList<{ int, int => int }>();
    operations.add({ int x, int y => x + y });
    operations.add({ int x, int y => x | y });
    int[][] param = { { 1, 2 }, { 3, 4 }, { 5, 6 } };
    for (int[] p: param) {
      for ({ int, int => int } op : operations) {
        System.out.println(op.invoke(p[0], p[1]));
      }
    }
  }
  

A closure can return another closure:

  { String => { int => String } } concat = 
    { String s => 
      { int n => String r = ""; for ( ; n > 0; n--) r += s; r } };
  

Function concat takes a single string argument and returns a function that takes a single integer argument and returns string.

  { int => String } concatABC = concat.invoke("ABC");
  String result = concatABC.invoke(3);
  

Each function that takes multiple arguments can be transformed into a function that takes a single argument. This transformation is called currying. For example, function plus can be transformed into anotherPlus:

  { int, int => int } plus = { int x, int y => x + y };
  { int => { int => int } } anotherPlus = { int x => { int y => x + y } };
  int threePlusFour = anotherPlus.invoke(3).invoke(4);
  

The reverse transformation is called uncurrying. Currying and uncurrying are used in functional programming. For more examples of functional programming in Java, see Luc Duponcheel's blog.

2 comments:

Lawrence Kesteloot said...

You wrote: "Function concat takes a single string argument and returns a function that takes a single string argument and returns string." That second "string" should be "integer".

Zdeněk Troníček said...

Thanks.