fun4j - functional programming for the JVM

Bringing more fun to Java programming

fun4j brings functional programming to the JVM. It's a framework that integrates major concepts from functional programming into the Java Platform.

At its core there is a lambda-to-JVM bytecode compiler. Thanks to some optimization techniques like tail code optimization (TCO) the compiler produces code that runs as fast as hand optimized Java code. The compiler uses the excellent Java bytecode assembler ASM

On top of this compiler you'll find a functional Java framework featuring higher order functions, partial application, support for Collections and Iterators, lambda terms, closures, etc.

In fun4j functions can be defined as anonymous classes. But it's also possible to define functions as lambda terms in classical LISP syntax. This avoids all the Java boilerplate code and thus improves code readability. LISP and java functions are totally interoperable.

As programming in fun4j is so much fun, I've also added a small LISP Read-Eval-Print-Loop (REPL) to interactively work with fun4j. The REPL comes with a little libray of useful functions and some example programs. E.G. a Lispkit interpreter and a LISP-1.5 interpreter.

New with release 1.1

With release 1.1 the Java Lisp integration has much improved. It's now possible to parse Vectors directly in Lisp code with the common [a, b, c] or [a b c] Notation.

There is now also a Dot operator that allow to access Java classes and instances directly from Lisp code. Please refer to the Java Lisp Integration tutorial for details.

Main features

Functional Java libray - allows you to use functions as first class citizens in your Java code.

- allows you to use functions as first class citizens in your Java code. Lambda to Java Bytecode Compiler - compiles lambda terms to efficient Java Bytecode

- compiles lambda terms to efficient Java Bytecode Integration of Java and Lisp code - mix Java and LISP as it fits to your programming task

- mix Java and LISP as it fits to your programming task Lisp Interpreter / Compiler - Allows to use the fun4j System interactively

- Allows to use the fun4j System interactively Lisp library - brings useful LISP functions, benchmarks and example code

- brings useful LISP functions, benchmarks and example code Functional Assembler- assembling Java Functions from AST-expression

Please check out the tutorial page for introductions to the main features.

Do we really need yet another functional library for Java ?

When presenting fun4j to the public I received some sceptical comments like: "There's already functionaljava, guava, lambdaj, op4j, commons functor, etc.: why a new functional library ?" or "We have Scala, Clojure, etc. Why yet another functional language for the JVM?". In the following section I try to explain how fun4j differs from those tools and why it is relevant.

No native support for closures in Java

Most functional frameworks for Java provide sophisticated means to deal with functions and to use them to filter and transform collections and other Java data structures. But I don't know of any that provides a convenient way to define new functions from scratch. This is caused by the limitaions of the Java language: as of now it does not provide native support for defining closures.

All functional libraries that I know of work around this limitation by defining functions as Function objects that implement an apply or evaluate method. Typically Function objects are then created in user code by defining anonymous inner classes, as in the following example:

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

This is quite verbose and just does not feel right.

Fun4j is different, it allows to write functions as lambda-terms in classic Lisp syntax. Thus the function add from the above example can be defined in fun4j as follows:

Function add = fn("(lambda (x y) (+ x y))");

This Lisp function is internally compiled into Java bytecode and is thus fully interoperable with "normal" Java code. The cool thing about this is that you can still stick to Java as your main language and use Lisp as an "embedded language" to define Function objects.

Not a new language

Scala, Clojure and the like are meant as fullblown standalone programming languages. They introduce new concepts like STM, agents, actors, etc.

Fun4j does not aim at inventing a new language. Even though fun4j comes with a full Lisp compiler and an interactive REPL, it's not intended as a completely independent language as Clojure or Scala. It simply provides a minimalistic functional subset of Lisp (comparable to the classic LISPKIT). You can use this Lisp implemenation as a standalone language. But you can also use it as an "embedded language" to conveniently define functions when using the Fun4j Java API.

Construction kit for implementing functional languages

At the core of fun4j there is an AST based functional assembler that allows to compose functional expressions (or lambda-terms) and compile them into Java Bytecode. (Here's the tutorial covering the basics.) This Assembler is agnostic of the actually implemented language. So you could use it to write an implementation of your functional language of choice by simply adding a Parser.

That said, fun4j is not limited to implement Lisp only. It could be used to implement other functional languages as well.

Project info

Download fun4j files

Project details and discussion

Our blog

Info for Developers

Join this project:

To join this project, please contact the project administrators of this project, as shown on the project summary page.

Get the source code:

Source code for this project may be available as downloads or through one of the SCM repositories used by the project, as accessible from the project develop page.

Continuous_Integration

Continuous Integration services are generously provided by CloudBees through their free FOSS program. You may find our nightly builds, including unit test coverage reports on our CI Server page at their site.

Powered by: