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 classes 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 functions as classes or as anonymous inner classes contain a lot of boilerplate coding even for simple function definitions. To ease the construction of function instances fun4j provides three alternative approaches.

use Java methods as functions

fun4j provides a way to create a Function instance from any Java Method. In the following code snippet you see how org.fun4j.Functions.functionFromMethod is used to create a sin function from the static method Math.sin.

import static org.fun4j.Functions.functionFromMethod;

Function sin = functionFromMethod(Math.class.getMethod("sin", double.class));
System.out.println(sin.apply(Math.PI/2.0));

In the following example the zero-argument instance method getSize() is used to create the function size. Calling size.apply(box) invokes the method call box.getSize(). Next the instance method contains(double x, double y) is used to construct the function contains. Calling contains.apply(box, 40.0, 40.0) invokes the mothd call box.contains(40.0, 40.0)

Box box = new Box(0.0, 0.0, 100.0, 200.0);

Function size = functionFromMethod(Box.class.getMethod("getSize", (Class<?>[]) null));
assertEquals(20000.0, size.apply(box));

Function contains = functionFromMethod(Box.class.getMethod("contains", double.class, double.class));
assertTrue((Boolean) contains.apply(box, 40.0, 40.0));

funcito style

Using Functions.functionFromMethod(...) drastically reduces boilerplate code. If you want to get rid of filling in Method names and parameter types there is an even more convenient mechanism available: contruction functions from methods in funcito style!

Funcito is a little framework that focusses on the construction of function instances for functional programming frameworks like Functional Java, Guava and Jedi-core. The resulting user code is very concise and clean, thus I have included function construction using the funcito idiom into fun4j. The following example shows how the functions size and contains from the previous section can be constructed using the fun4j funcito style syntax:

import static org.fun4j.Functions.callsTo;
import static org.fun4j.Functions.functionFor;

size = functionFor(callsTo(Box.class).getSize());
assertEquals(20000.0, size.apply(box));

// the 0.0 arguments don't represent actual values they just serve as placeholders for a double value:
contains = functionFor(callsTo(Box.class).contains(0.0, 0.0));
assertTrue((Boolean) contains.apply(box, 40.0, 40.0));        

The cool thing about this idea is that callsTo(Box.class) generates a mock instance that allows to write the candidate method exactly as any other method call. Thus it's type safe at compile time and IDE code completion is available. The only disadvantage: due to limitation of the CGLIB codegenerator this mechanism does not work for static methods.

create functions from lambda terms

Both Functions.functionFromMethod and Functions.functionFor allow to create functions based on existing Java methods. They do not provide a mechanism to write new functions from scratch.

In order to write new functions from scratch fun4j provides a way to define functions as lambda-terms in classic Lisp-syntax. Here is a short example that demonstrates the basic idea:

import static org.fun4j.Template.fn;

Function add = fn("(lambda (x y) (+ x y))");
assertEquals(16, add.apply(9,7));

Obviuosly it's much more concise to define the function add in this way then by using the notorious Java anonymous inner class syntax. Please follow this link to read a more in depth tutorial on using Lisp/Scheme in fun4j.

The fun4j Collection API

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

Using Function can be very useful when 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);

import static org.fun4j.Collections.asCollection;
import static org.fun4j.Collections.map;

// construct a collection from a set of arguments
Collection<Integer> col = 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 = map(pow2, col);

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

Here you can see how map is implemented:

public static <E, F> Collection<F> map(Function fun, Collection<E> col) {
    Collection<F> result = new ArrayList<F>(col.size());
    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:

import org.fun4j.Predicate;
import static org.fun4j.Collections.filter;

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

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

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

It might be noteworthy here that Predicate is a covariant extension of the Function interface. A Predicate must always return a Boolean value.

public interface Predicate extends Function {

    @Override
    Boolean apply(Object... args);
         
}

This works thanks to Java's support for covariant return types. For details have a look at org.fun4j.compiler.Expression.compile(...) where a special bridge method is generated to delegate to the covariant method.

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:

import static org.fun4j.Collections.foldright;

Collection<Integer> col = 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 = 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 either re-use existing Java methods by wrapping them to functions using Functions.functionFromMethod or Functions.functionFor or to write functions in traditional Lisp / Scheme Syntax. follow this link to learn more more about this approach.

Some advanced examples

In this section I'm going to present some more advanced examples to demonstrate how typical problems can be solved using fun4j. The examples are based on examples from the Functional Java site. So these examples also allow you to directly compare the look and feel of both fun4j and Functional Java.

Collections.exists

Checks for the existence of a String that has all lower case characters.

import static org.fun4j.Collections.asCollection;
import static org.fun4j.Functions.functionFromMethod;
import static org.fun4j.Template.define;

Collection<String> col = asCollection("Hello", "There", "what", "DAY", "iS", "iT");
final Predicate isLowerCase = (Predicate) functionFromMethod(Character.class.getMethod("isLowerCase", char.class));
define("isLowerCase", isLowerCase);
// 1. define function in Java Syntax:
assertTrue(
    Collections.exists(new Predicate() {
        public Boolean apply(Object... args) {
            return Collections.forAll(isLowerCase, Collections.fromString((String) args[0]));
        }
    }, col)
);

// 2. define function in LISP Syntax:    
assertTrue(
    Collections.exists(predicate("(lambda (str) (Collections.forAll isLowerCase (Collections.fromString str) ))"), col)
);    

Collections.filter

Filters all elements from a Collection that fulfill a certain criteria. In this case, we use the even predicate to select only the even numbers from a list.

import static org.fun4j.Collections.*;

Collection<Integer> col = asCollection(97, 44, 67, 3, 22, 90, 1, 77, 98, 1078, 6, 64, 6, 79, 42);
Collection<<Integer> result = filter(predicate("(lambda (n) (zero? (% n 2)))"), col);
System.out.println(result);

Collections.foldleft

Reduces the list applying a function per element. In this case, the fold sums the elements with a starting value of 0.

Collection<Integer> col = asCollection(97, 44, 67, 3, 22, 90, 1, 77, 98, 1078, 6, 64, 6, 79, 42);
Integer result = foldleft(fn("(lambda (i j) (+ i j))"), 0, col);
assertEquals(1774, result);

Collections.forall

Checks that all Strings in a colletcion have only lower case characters. In this case, the check fails because of the case of "There".

Collection<String> col = asCollection("hello", "There", "what", "day", "is", "it");
final Predicate isLowerCase = (Predicate) functionFromMethod(Character.class.getMethod("isLowerCase", char.class));
define("isLowerCase", isLowerCase);
       
// 1. define function in Java Syntax:
assertFalse(
    Collections.forAll(new Predicate() {
        public Boolean apply(Object... args) {
            return Collections.forAll(isLowerCase, Collections.fromString((String) args[0]));
        }
    }, col)
);

// 2. define function in LISP Syntax:
assertFalse(
    Collections.forAll(predicate("(lambda (str) (Collections.forAll isLowerCase (Collections.fromString str) ))"), col)
);

Collections.map

Maps a function across a list of integers. This example adds 42 to each element of the list to produce a new list.

Collection<Integer> ints = asCollection(1, 2, 3);
Collection<Integer> actual = Collections.map(fn("(lambda (i) (+ i 42))"), ints);
assertEquals(asCollection(43, 44, 45), actual);

Collections.sort

Sorts the given list:

Predicate intOrd = predicate("(lambda (x y) (> x y))");
List list = (List) asCollection(97, 44, 67, 3, 22, 90, 1, 77, 98, 1078, 6, 64, 6, 79, 42);

assertEquals(asCollection(1, 3, 6, 6, 22, 42, 44, 64, 67, 77, 79, 90, 97, 98, 1078), sort(list,intOrd));
// sorting is NOT destructive !
assertEquals(asCollection(97, 44, 67, 3, 22, 90, 1, 77, 98, 1078, 6, 64, 6, 79, 42), list);

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));