install

tutorials

- Java API

- Java + LISP

- Lisp Repl

- Assembler

Javadoc

Lisp manual

fun4j - functional programming for the JVM

The central idea: functions as first class citizens

fun4j builds upon one central concept: functions as first class citizens. As the Java programming language does not have native support for functional programming we have to emulate it using object-oriented techniques: We need a Function object that allows to deal with functional abstractions. The base idea of a function is that it is a mapping that is applied to 0..n input arguments to result in one output value. This notion is expressed in the following definition of the Function interface:

package org.fun4j;

public interface Function {

    /**
     * Apply this function to the given arguments.
     * 
     * @param args the arguments passed to the function call
     * @return the result of applying the function to its arguments
     * 
     */
    Object apply(Object... args);
        
}

Function objects implementing this interface can be passed as ordinary Object instances within Java code. So it's quite straightforward to use typical patterns of functional programming like the usage of higher-order functions to define transformations on Collections. I'll come back to this interesting topic shortly.

To create such a Function object in your Java code you can define it as an instances of anonymous classes like in the following code:

Function add = new Function(){
    @Override
    public Object apply(Object... args) {
        return (Integer) args[0] + (Integer) args[1];
    }    
};       

This new Function object can now be invoked by calling its apply Method, here we using it to calculate 17 + 6:

System.out.println(add.apply(17,6));

Of course Functions can also defined as ordinary named classed like in the following definition:

public class Hash implements Function {
     
    @Override
    public Object apply(Object... args) {
        return new Integer(args[0].hashCode());
    }  
}

This Function can then be used as follows:

Function hash = new Hash();
System.out.println(hash.apply("hello world"));

Both ways of creating function objects contain a lot of boilerplate coding for just a few simple function definitions. To make things easier fun4j provides an elegant way to define functions as lambda-terms in classic Lisp-syntax. please follow this link to read the respective tutorial.

Now that we know how to construct Functional objects we want to know how fun4j can help us to use them in Java code.

Partial Application

Partial application allows to bind data to the Variables of a Function. Take for example the Function add(m,n) => m + n. This function has two variables m and n. The following code shows how to create a partial application by binding the values 17 to m:

// org.fun4j.Template is the central facade to the fun4J API. 
// A default instance can be obtained by a static import:
import static org.fun4j.Template.fun4j;

Function add = new Function(){
    public Object apply(Object... args) {
        return (Integer) args[0] + (Integer) args[1];
    }    
};

Function add17 = fun4j.bind(add, 17);
assertEquals(23, add17.apply(6));

As you can see a partially applied function is again a function. Thus it can be evaluated by calling the apply() method.

This short example demonstrate that partial application can be used to preserve state and to produce delayed computations that can be reached around in an application until it they are finally executed.

How can this be useful? Consider the computation of VAT. It can be considered as a partial application of the function mul(x,y) => x * y to the actual tax-rate. The following code shows how this can be done with fun4j:

Function mul = new Function() {
    protected Object apply(Object... args) {
        Double x = (Double) args[0];
        Double y = (Double) args[1];
        return x * y;
    }
}; 

Function germanVat = fun4j.bind(mul, 0.19); 
Function britishVat = fun4j.bind(mul, 0.175);
System.out.println(germanVat.apply(495.00));
System.out.println(britishVat.apply(495.00));

The fun4j Collection API

Using Function can be very useful wehen dealing with Collections. Let's have a look at some examples. First we define a Collection of Integers [1, 2, 3, 4] and a Function pow2 that computes the square of an Integer.

Now we want to apply this function to each element in the collection. A typical Java solution would explicitely iterate over the collection and collect the results of the function applications into a new Collection. With fun4j we do this with a single statement: fun4j.map(pow2, col);

// org.fun4j.Template is the central facade to the fun4J API. 
// A default instance can be obtained by a static import:
import static org.fun4j.Template.fun4j;

// construct a collection from a set of arguments
Collection<Integer> col = fun4j.asCollection(1, 2, 3, 4);

// define powers2 function: f(x) => x*x
Function pow2 = new Function(){
    @Override
    public Object apply(Object... args) {
        return (Integer)args[0] * (Integer)args[0];
    }
};

// map applies a function to all elements of a collection
Collection<Integer> result = fun4j.map(pow2, col);

// crosscheck: 
assertEquals("[1, 4, 9, 16]", result.toString());

Here you can see how map is implemented:

public  Collection map(Function fun, Collection col) {
    Collection result = new ArrayList();
    for (E el : col) {
        result.add((F)fun.apply(el));
    }
    return result;
}

Functional languages feel at home with higher order functions like map, that take other functions as arguments and compose complex computations from simple functions.

Here is another example:

// define a predicate that returns true for even numbers
Function even = new Function() {
    @Override
    public Object apply(Object... args) {
        Integer i = (Integer) args[0];
        return (i % 2 == 0); 
    }
};

// compute pow2 for all even numbers in col
result = fun4j.map(pow2, fun4j.filter(even, col));
assertEquals("[4, 16]", result.toString());

Here we are computing the squares for all even numbers in our collection. The method fun4j.filter returns a Collection of all elements of the input Collection that match the filter predicate.

Fun4j also provides classic higher order functions like foldleft and foldright. Here comes an example where foldright is used to sum up all elements of a Collection by sequentially adding each element of the Collection to an accumulator, which is initialized with 0:

Collection col = fun4j.asCollection(1 , 2, 3, 4, 5, 6, 7, 8, 9, 10);
Function add = new Function() {
    public Object apply(Object... args) {
        return (Integer) args[0] + (Integer) args[1];
    }
};
Integer sum = fun4j.foldright(add, 0, col);
assertEquals(new Integer(55), sum);

After working through these examples you might think: "Ok, this looks nice. BUT writing simple operations like an addition function as an anonymous inner class is not an elegent solution...".

Yes, that a valid point. The fun4j answer to this issue is to write functions in traditional Lisp Syntax. follow this link to learn more more about this solution.