Functional Concepts

a Java simulation

This article is a follow up to the one about , suggested by @pcolomb. As I’m not yet fully aware of Java 8 lambda to add snippets, I decided to present a way to simulate these concepts in pure Java.

The proposed version is not really usable, and probably performs badly, but can help to understand the underlying concepts (and it’s fun).

Lambda

As explained in the , lambda are anonymous functions, that can be created on demand. We’ll create a class that simulate an unary function.

We thus need to create a generic class simulating anonymous function creation, having A → B as signature. This can be defined as:

First try (Lambda.java)
    1 
    2 abstract class Function<A,R> {
    3     public abstract R call(A arg);
    4 }
    5 
    6 class Lambda {
    7     public static void main(String[] args) {
    8 
    9         Function<Integer,Integer> doubler = new Function<Integer,Integer>(){
   10             public Integer call(Integer arg) { return 2*arg; }};
   11 
   12         System.out.println(doubler.call(21));
   13     }
   14 }

It works! To better integrate this, it would be nice that the “function” implements Callable, which would allow to use it in a context needing this interface. Let’s try to modify our class accordingly. Since the argument can’t be given to call, we must keep it in the object’s internal state, as a private attribute.

Callable lambda (LambdaCallable.java)
    1 import java.util.concurrent.Callable;
    2 
    3 class NotBoundFunctionException extends Exception { }
    4 
    5 abstract class Function<A,R> implements Callable<R> {
    6     private A _arg;
    7     public A arg() { return this._arg;}
    8     public void arg(A arg) { this._arg = arg; }
    9 
   10     public Function() {}
   11     public Function(A arg) { this.arg(arg); }
   12 
   13     public Function<A,R> bind(A arg) { this.arg(arg); return this; }
   14 
   15     protected abstract R callMe();
   16     public R call() throws Exception {
   17         if ( this._arg == null) { throw new NotBoundFunctionException(); }
   18         return this.callMe();
   19     }
   20     public R call(A arg) throws Exception {
   21         return this.bind(arg).call();
   22     }
   23 }
   24 
   25 class LambdaCallable {
   26     public static void main(String[] args) {
   27 
   28          Function<Integer,Integer> doubler = new Function<Integer,Integer>(){
   29             protected Integer callMe() { return 2*this.arg(); }};
   30 
   31         try {
   32 
   33             doubler.arg(21);
   34             System.out.println(doubler.call());
   35 
   36             System.out.println(doubler.bind(12).call());
   37 
   38             System.out.println(doubler.call(21));
   39 
   40         } catch (Exception e) { System.exit(1); }
   41     }
   42 }

Note the Function<A,R> bind(A arg) method, having a fluent interface flavour, allowing to easily chain methods. This bind method is equivalent to partialize the function, that can therefore be called without arguments, and thus follow the Callable interface. This partial application corresponds to a closure, the closed variable being kept in a function private attribute. Finally, call overloading makes the use of the function more natural, keeping the interface compatibility at the same time (beware the internal side effect, since the object state is changed).

We just thus simulated a closure allowing a partial application.

Polyadic Functions and Currying

The Function object gives us unary functions, which is somewhat limited. How can we create functions with several arguments? We could create a generic class for every arity, but there is a simpler solution: create curryfied functions, that is a function of just one argument, returning a function of just one argument, etc.

It is already possible “by hand”, with what we have. Let’s create a function add: Interger → Integer → Integer with our first lambda version.

Polyadic function by manual currying (Curry.java)
    1 
    2 abstract class Function<A,R> {
    3     public abstract R call(final A arg);
    4 }
    5 
    6 class Curry {
    7     public static void main(String[] args) {
    8         Function<Integer,Function<Integer,Integer>> add = new Function<Integer,Function<Integer,Integer>>(){
    9             public Function<Integer,Integer> call(final Integer a) {
   10                 return new Function<Integer,Integer>(){
   11                     public Integer call(final Integer b) {
   12                         return a + b;
   13                     }
   14                 };
   15             }
   16         };
   17         try {
   18             System.out.println(add.call(21).call(21));
   19 
   20             Function<Integer,Integer> partialAdd = add.call(21);
   21             System.out.println(partialAdd.call(21));
   22 
   23         } catch (Exception e) { System.exit(1); }
   24     }
   25 }

Not really readable, but it works. Note that arguments (at least a must be finals, since they are used in an anonymous inner class; but hey, we are doing functional programming right?

On fait ici une « vrai » fermeture, au sens fonctionnel, puisque la variable a est bien capturée directement dans la définition de la fonction interne ; mais notre fonction n’est plus Callable. On est ici très proche de la version Javascript de curryfication simple. This one is a “true” functional closure, since the a variable is captured in the internal function definition; but this function is no more Callable. This approach is very similar to the Javascript one.

Let’s use our Callable version of Function:

Callable polyadic function by manual currying (CurryCallable.java)
    1 import java.util.concurrent.Callable;
    2 class CurryCallable {
    3     public static void main(String[] args) {
    4         Function<Integer,Function<Integer,Integer>> add = new Function<Integer,Function<Integer,Integer>>() {
    5             protected Function<Integer,Integer> callMe() {
    6                 final Integer first = this.arg();
    7                 return new Function<Integer,Integer>(){
    8                     private Integer curry = first;
    9                     protected Integer callMe() {
   10                         return this.arg() + curry;
   11                     }
   12                 };
   13             }
   14         };
   15         try {
   16 
   17             System.out.println(add.call(21).call(21));
   18 
   19             Function<Integer,Integer> partialAdd = add.call(21);
   20             System.out.println(partialAdd.call(21));
   21 
   22             Callable<Integer> callableAdd = add.call(37).bind(1300);
   23             System.out.println(callableAdd.call());
   24 
   25         } catch (Exception e) { System.exit(1); }
   26     }
   27 }

Ouch! It hurts, but it works, and with the previous features.

And what if we want both? The “ease” of function definition and the greater flexibility? In object oriented paradigm, we would use delegation, in functional programming, it’s called function composition, but it’s the same principle. Let’s create a “function” that takes a function and returns partial, augmented with the second approach methods. It’s the decorator pattern from a functional point of view (it’s the name used is Python world for such a thing). It’s the same approach, but instead of redefining callMe, we create a fun attribute containing a function that will be called with the arg value (thus the delegation).

Automatically Callable polyadic function by composing (CurryComposed.java)
    1 import java.util.concurrent.Callable;
    2 
    3 class NotBoundFunctionException extends Exception { }
    4 class FunctionUndefinedException extends Exception { }
    5 
    6 abstract class Function<A,R> {
    7     public abstract R call(final A arg);
    8 }
    9 
   10 class CallableFunction<A,R> implements Callable<R> {
   11     private A _arg;
   12     public A arg() { return this._arg;}
   13     public void arg(A arg) { this._arg = arg; }
   14 
   15     private Function<A,R> _fun;
   16     public Function<A,R> fun() { return this._fun; }
   17     public void fun(Function<A,R> fun) { this._fun = fun; }
   18 
   19     public CallableFunction() { }
   20     public CallableFunction(A arg) { this.arg(arg); }
   21     public CallableFunction(Function<A,R> fun) { this.fun(fun); }
   22     public CallableFunction(Function<A,R> fun, A arg) {
   23         this.fun(fun);
   24         this.arg(arg);
   25     }
   26 
   27     public Callable<R> bind(A arg) { this.arg(arg); return this; }
   28 
   29     public R call() throws Exception {
   30         if ( this.arg() == null) { throw new NotBoundFunctionException(); }
   31         if ( this.fun() == null) { throw new FunctionUndefinedException(); }
   32         return this.fun().call(this.arg());
   33     }
   34     public R call(A arg) throws Exception {
   35         return this.bind(arg).call();
   36     }
   37 }
   38 
   39 
   40 class CurryComposed {
   41     public static void main(String[] args) {
   42         Function<Integer,Function<Integer,Integer>> add = new Function<Integer,Function<Integer,Integer>>(){
   43             public Function<Integer,Integer> call(final Integer a) {
   44                 return new Function<Integer,Integer>(){
   45                     public Integer call(final Integer b) {
   46                         return a + b;
   47                     }
   48                 };
   49             }
   50         };
   51 
   52         try {
   53 
   54             System.out.println(add.call(21).call(21));
   55 
   56             Function<Integer,Integer> partialAdd = add.call(21);
   57             System.out.println(partialAdd.call(21));
   58 
   59             CallableFunction<Integer,Integer> callableAdd = new CallableFunction<Integer,Integer>(partialAdd);
   60             System.out.println(callableAdd.call(21));
   61 
   62             System.out.println(callableAdd.bind(1316).call());
   63 
   64             System.out.println((new CallableFunction<Integer,Integer>(add.call(668))).bind(669).call());
   65 
   66         } catch (Exception e) { System.exit(1); }
   67     }
   68 }