Functional libraries for Java

Over the past few months I have collected a few links for Java functional libraries (I haven't actually used any of them yet in any major project). Thought it might interest people here:


http://www.cs.chalmers.se/~bringert/hoj/ programmer (includes Java 5.0 generics support). Little documentation.


http://jakarta.apache.org/commons/sandbox/functor/ doesn't look like it is maintained, doesn't support generics. Little documentation.


http://devnet.developerpipeline.com/documents/s=9851/q=1/ddj0511i/0511i.html
library.


http://functionalj.sourceforge.net

http://www.functologic.com/orbital/

http://jga.sourceforge.net/ programming in java (includes generics). Looking forward to more documentation, perhaps better organization of the API.




Java 5.0 also has an interesting interface (same as Oz, AliceML?):
java.util.concurrent.Future with the following description:

"A Future represents the result of an asynchronous computation. Methods are provided to check if the computation is complete, to wait for its completion, and to retrieve the result of the computation"


I read one rumor (on theserverside.com...can't find it any more) that Java 7.0 will have something like C#'s delegates.


There was another comment from Javalobby.org about simulating continuation using a new library in Java 5.0 (I believe from java.util.concurrent.*)...can't find that either.



Googling for "functional c#" brings up some blog enteries where people show how to do functional style programming in C#. ACM has a couple of papers on functional programming in Java/C#, I'm trying to find those again.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

I've been thinking about this

I've even written some code. One huge advantage purely applicative data structures have is that synchronization is much less necessary. Add in transactional memory and maybe channels, and you have yourself a very powerfull multithreading infrastructure which is gaurenteed to be race condition and deadlock free.

Some problems with this in practice, I've found. First of all, purely functional code allocates like crazy. If Java really does have fast (~10 clock cycles) allocation, this isn't a problem. If, as Java users constantly tell me, Java allocation is still slow (compared to SML/Ocaml/Haskell/etc. allocation) then this becomes a major problem.

Another problem is the profileration of classes and interfaces. Instead of just being able to do (in Ocaml) List.map (fun x -> x + 1) lst, you have to do:

lst.map (new Mapper() {
    public Object map(Object x) {
        return new Integer(((Integer) x).intValue() + 1);
    }
}
with, of course, the proper Mapper interface defined.

Ignore the interface as just the cost of doing business, it should be obvious that a) this code is signifigantly less readable and less maintainable (even if the maintainer knows functional programming and understands the pattern being implemented) than the original functional code. Especially when compared to the Iterator loop ("classical Java") version of the code. The Ocaml version is signifigantly shorter (and more clear, once you're comfortable with map) than either version of the Java code- but we're not coding this in Ocaml. The question is, which is easier to maintain: the functional java version, or the Iterator loop version?

And b) you've created a new anonymous inner class. Ever had a 200 line object compile into almost 2 dozen different .class files? I have. Each of those class files now has to be individually loaded and JIT'ed- signifigantly slowing down the loading of the code.

It can be done- the question is, can it be done efficiently? IMHO, the jury is still out on that one.

This is, of course, ignoring the cultural and social problems this approach has. The code is bad enough to maintain with a programmer who already knows the patterns and philosophies and data structures and algorithms being used. Drop Joe Average Java Programmer into this code and watch his head explode. Then, for more fun, try explaining the idea to him. Then try to write a JavaDoc comment explaining the idea that would allow him to get it without six months of personal tutorials from you.

The other problem with this is the temptation to revert. The multithreading advantages of purely applicative data structures only shows up with pure code. There will always be the temptation to revert, and use just a tensy little bit of imperitive data structures- just to get something working and out the door, just for the performance boost, I'll fix it later I swear. Say hello to race conditions.

No- I'm comming to the conclusion that when in Rome, you wear a toga.

Re: you have to do

It doesn't have to be quite that verbose.
Here
is what you can do in pre generics Java (using reflection):

Algs.map(lst,
         new Function() {
           public int with(int x) {
             return x + 1;}});

One problem

this only works on lists of ints (pre-generics). Generics help, but the main problem is that you need an anonymous inner class in order to pass in a function.

for reference, in Scala this

for reference, in Scala this would look like:

lst.foreach(x => x + 1);

A fold:

lst.foldl(0)((sum,x) => x + sum);

When the expected type of an argument is a function, Scala has a very lightweight syntax.

To be fair...

...with Java 1.5 autoboxing would make the map methods' content look lot more reasonable, and by parameterizing Mapper you could elminate the cast and make it type safe. I'm not sure I would care how costly the extra anonymous class would be, as loading and JITing it would only happen once and would hopefully be dominated by whatever processing the loop is doing.

I've used this method fairly extensively in one project of mine, and usually the choice between this and a standard looping construct would come down to re-use: if I found myself writing the same looping code in other places, I'd pull it out into a class. In that particular project threading and synchronization was achieved through other means, so I didn't need to consider it. I also didn't have to worry about other people maintaining it, so complexity wasn't relevent. The biggest problem I encountered with it was when the body's action resulted in multiple results; creating a custom value class to return them or using some generic tuple class were both quite awkward.

They're better than nothing, but anonymous class syntax will never be as nice as an anonymous function or closure.

Re: O'Caml vs. Java syntax

I'd agree the Java syntax is just lame; presumably it is always what one gets when shoe-horning a different paradigm into something already fixed in another style. Try another language that targets the JVM? Perhaps Scala, or even Jython? I realize that is sort of side-stepping the issue entirely.

Thanks for the pointer

to Scala. I'd think it'd still have the sensitivity to allocation speed (this is a problem with all functional languages) and the anonymous inner class problem (which is an effect of the JVM)- but it looks like it solves most of the syntax problems.

Scala is the way to go

You really should consider Scala if you want to program in a functional style in the JVM. Syntactical conveniences aside (higher-order functions, ease of declaration for anonymous functions, etc), it has a better type system that tries to merge functional and OO styles nicely, it optimizes tail recursion (but not general tail calls) and many more good stuff (combinator parsing!).

I can't say much about the performance of functional code, but I believe there are no good reasons for it to be far worse than imperative Java code.

Do you have any experience with Scala?

I'm looking at it for some work I may be doing. We definately need to be able to access legacy Java libraries- but we miss the power and experessiveness of Ocaml. Scala, which appears to be the bastard child of Ocaml and Java, would be perfect. I'd even be willing to accept a performance hit- write the 90% of the code that takes only 10% of the time in Scala, then write the 10% of the code that takes 90% of the time in "high-performance" Java. It'd still be a net win, IMHO.

The documentation has some tantalizing hints about Erlang-like distribution and fail-over features, but I haven't been able to find anything more about this. Are these features real, or just possible?

Not much right now, but...

Well, I just began learning Scala, but I can tell you I don't intend to use Java anymore, except when strictly necessary. The good thing about it is that it's multi-paradigm, so if the functional style is lacking performance, you can write an imperative implementation in Scala, very similar to what you would write in Java, and with roughly the same performance characteristics.

And yes, I forgot to mention it in my original message, but the concurrency abstractions in Scala are great. Erlang-like message-passing concurrency is supported by existing classes. Take a look at the "Scala by Example" document, its last chapter is about concurrency.

it inherits Java's broken concurrency support?

I recalled this old mailing-list comment

"This is BTW my main gripe about Scala: it inherits Java's broken concurrency support, making it uninteresting for any application with significant concurrency issues, nonwithstanding the cute Erlang-like actor example in the beginning of the manual."

Ulf Wiger on comp.lang.functional

He goes on to say "Perhaps your best bet is to simply go with JCSP, if you really need to use Java..."

Broken Concurrency

In what way is Java's concurrency broken? Java 5’s concurrency offers great performance and multi-processor support. Util.concurrent provides a nice framework of high-level high-performance concurrency abstractions which build upon Java's underlying primitives. Doug Lea recently said that if Java concurrency code is only ten times faster than the equivalent C code then it means that you haven't started to optimize (Java) yet.

Many systems which purport to do concurrency better, like Erlang, are actually only solving the much simpler and less useful problem of single-processor concurrency. In ten years we're all going to have 100 CPU cores/threads on our desktops and single-processor concurrency systems aren't going to be useful for anything. Already Sun has a CPU with 32 simultaneous processing threads.

Many systems which purport to

Many systems which purport to do concurrency better, like Erlang, are actually only solving the much simpler and less useful problem of single-processor concurrency.

Can you be more specific about exactly which languages you have in mind and why you think they only support single-processor concurrency?

Let's also try to distinguish between language issues and limitations that apply only to a specific implementation.

Links

Can you be more specific about exactly which languages you have in mind and why you think they only support single-processor concurrency?

Erlang ( ">from LtU post) and Io (from the author's blog).

Let's also try to distinguish between language issues and limitations that apply only to a specific implementation.

I really love the Io language, but it is far more difficult to get it to take advantage of all of the CPU's of a multiprocessor system than it is with Java. There is only one implementation of Io so I don't know if you can distinguish between the implementation and the specification.

In the end, people need to run their code against implementations, not merely specifications, and until Erlang actually has a multi-processor implementation, any advantages it has over Java (in this environment), are purely hypothetical.

Java concurrency

The original Java concurrency implementation, which is based on monitors, is broken. This has been documented by such luminaries as Per Brinch-Hansen. The concurrency code in Java 5 (which is based on Doug Lea's concurrency utilities) apparently does a good job of shielding the user from Java's peculiar implementation of monitors. But they are a recent improvement, any many people still retain the impression of Java concurrency they got from the earlier implementation.

Note that there is no incompatibility between JCSP and the Java concurrency primitives - JCSP is implemented on top of them, just as util.concurrent is. In fact, it seems likely that JCSP will eventually be ported to the new util.concurrent framework, since it will allow a cleaner implementation. What JCSP offers is a higher-level concurrency abstraction that is easier to work with, and more amenable to analysis. At one point it was being proposed as the concurrency library for Java 5, but util.concurrent won out in the end because (in my opinion) it provides an abstraction layer that is more familiar to most programmers.

Java's concurrency is broken

Java's concurrency is broken compared to Erlang in that the thread model uses heavyweight OS threads. This does has the advantage of being multiprocessor but has the disadvantage of not being able to use the 'everything is a process' model that Erlang encourages.

Having very fast process creation times and the ability to create many thousands, if not millions, or processes makes concurrency oriented programming easier.

Note that Erlang maybe getting an SMP compatible implementation:
http://www.erlang.se/euc/05/1710OTPupdate.ppt

What about Bigloo Scheme?

It compiles Scheme to JVM byte code, and easily interfaces with Java. It can also compile to C or .Net, so you can build libraries usable by many other languages. It also supports type inference.