Functional programming in Java

(Link)

Vadim Nasardinov pointed out this article, which although pitched at an introductory level, provides a reasonably thorough overview of functional programming possibilities in Java. It focuses on the use of closures and higher-order functions, via Java's anonymous inner classes, and works its way up to "using closures to implement business rules" as one of its concrete examples.

Perhaps a little too introductory for LtU, but articles like this can be a useful starting point when talking to Java programmers who've had little or no previous exposure to FP, or who need some hints about useful ways to apply FP concepts in Java. Using anonymous inner classes to implement e.g. GUI event listeners in Java is common practice, but often, more advanced and useful possibilities are overlooked.

Comment viewing options

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

FC++ Boosted

On a related note, the magnificent FC++ library is moving to Boost. FC++ allows C++ programmers to write functional code in a familiar language.

FC++ not boosted!

That message was from a while ago - the library was rejected, due partially to its overlap with Boost features already supporting functional programming.

Re: FC++ not boosted!

Thank you Jim. Due diligence was performed. I checked Boost's announce list beforehand, but found no such announcement. Can you provide a relevant URL?

FC++ remains a fantastic library even if outside Boost. Personally I think Boost should drop its lambda library in favor of FC++.

Rejection notice

Re: Rejection notice

Why, how generous of them:

Note that while the library is not accepted, the author has successfully established some of the merits of the functional programming paradigm and we should not require him to re-establish those same points in a future review. For that matter, I'm not convinced that we should have asked him to establish these points in the first place.

So some resistance to FC++ came from persons who required its author to explain the merits of functional programming. And these are C++ experts.

Boost hateration

And these are C++ experts.

Well . . . Anyone can join the list and participate in a review.

Also, as I recall, there was just one person (out of maybe 15 who bothered to review the library, out of maybe 1000 on the boost-devel list) who doubted the benefits, and mostly of lazy lists. He also talked quite a bit about performance.

Review of the Boost review

With your permission then, a review of the review may have value, because they intend to revisit the no-go decision at a later time.

Their remarks contradict yours rather plainly:

However I found it disturbing that during the review a number of traditional/ imperative-style C++ programmers were just not "getting it" about FP [functional programming].

So we have the same old problem of reaching the C++ crowd.

This was a very difficult decision, and I spent a long time sitting on the fence...in the end I received approximately 4 no votes and 7 yes votes...

Boost deserves credit for doing the review. The votes were almost two to one in favor. Both columns (yes/no) agreed that FC++ will get another shot at inclusion. That is the good news -- or bad news, if it affects FC++ in the wrong way.

There are two basic problems. The first is the value of multiparadigm programming (MP). The second is the view of a monolith with substantial overlap.

FC++ is a largely monolithic library with a fair [later called substantial] degree of overlap with other boost components. This led to a good deal of confusion/discussion during the review period. Such a state of affairs (monolith with substantial overlap) could conceivably be acceptable if there were clear problems for which FC++ was a uniquely suited practical solution....I don't believe that the *practical* value of FC++ as a *monolithic* embedded DSL in C++ supporting mixed paradigm programming has been satisfactorily established....If the authors were to break FC++ into smaller pieces and should they participate in a future lambda, phoenix, FC++ merger then the above concerns would be addressed.

MP has immense practical value. No one should argue that point. Sadly, we still do. I am wiping my tears away with tissue paper right now. If people aren't "getting it" about FP, then by definition, they have no basis to dismiss FP or MP. It is just unknown territory.

The more subtle matter is the monolithic charge. Now I haven't any details to refute it. Nor do I think refutation desirable. Maybe the charge sticks.

All I would propose is that hard evidence may need a different light of interpretation. The Boost folks puzzle over FP and MP, by their own admission. So a bias may distort their judgment about what is, and what isn't monolithic. The same data points that suggest, to C++ gurus, a "monolith," may suggest, to multiparadigm gurus, "flexibility."

Let me elaborate. Here we have FC++, there we have Boost. Boost admits to substantial overlap between them. So they are doing similar things. That fact speaks volumes. Has Boost been inching towards FP on an ad-hoc, piecewise basis? If not, then why is it doing so many similar things? The question then becomes, Which library is more coherent? FC++ provides a very capable functional DSL, designed from scratch with FP in mind, whereas Boost provides....components.

So a Devil's advocate could argue for scrapping Boost components and rewriting them more cleanly under C++ with FC++ as a DSL -- i.e., a MP language. That MP power could define exactly the right path to cool, new Boost libraries ad infinitum. Maybe FC++ seems difficult to break up because it makes too much sense to keep together. Maybe Boost, not FC++, has been doing things wrongly all along.

The question may have arisen during review: How might Boost components appear if built on top of C++/FC++? I suspect the answer is that they would be clean, polished, smaller, and easier to maintain. That statement I base on my own experience in MP.

The statement is merely a straw-man, meant for attack. It is not The Answer. I disclaim any detailed knowledge of library internals, and leave myself open to contrary evidence. Boost is open-minded about FP and MP, for which they earn my thanks.

Errata

I think calling FC++ a DSL is wrong. FP is FP. A language is only domain-specific where there is a domain limiting its uses. To call FP a domain is really stretching things. That's like calling C a DSL.

The other correction is that, in my Devil's hypothetical, some Boost components would simply disappear, since FC++ handles their capabilities. Others would be streamlined.

Review (of review)^n where n = 2

Their remarks contradict yours rather plainly:

However I found it disturbing that during the review a number of traditional/ imperative-style C++ programmers were just not "getting it" about FP [functional programming].

I don't see how that contradicts what I said.There was one notable who said that he understood lazy lists, and that they were useless, partly becuase of performance issues. That statement doesn't preclude people who didn't review the library, but did post seeking further explanations of FP.

All I would propose is that hard evidence may need a different light of interpretation. The Boost folks puzzle over FP and MP, by their own admission. So a bias may distort their judgment about what is, and what isn't monolithic. The same data points that suggest, to C++ gurus, a "monolith," may suggest, to multiparadigm gurus, "flexibility."

The Boost folk don't "puzzle over FP by their own admission"! At worst, some people didn't get it! A whole mess of other people did get it!

Second, the monolithic issue has nothing to do with FP or MP, it has to do with modularity, compile times, documentation, namespace issues, etc. There are a million reasons to split libraries into smaller pieces. Don't call out Boost bias without considering the evidence.

Has Boost been inching towards FP on an ad-hoc, piecewise basis? If not, then why is it doing so many similar things? The question then becomes, Which library is more coherent? FC++ provides a very capable functional DSL, designed from scratch with FP in mind, whereas Boost provides....components

Which libraries are more coherent is not the only question: performance, simplicity, and readability are all issues. In addition, it is not a good idea to break existing code by removing, say, the old Boost lambda library. Even Brian McNamara wasn't proposing that. Since we're going to have the old lambda library (which has very nice syntax, BTW), then the new lambda syntax should complement it.

In addition, even McNamara wasn't suggesting we "add FP to C++". Each component should stand on it's own. Why does C++ need monads? There's a 37k header file if you do, and one paragraph of documentation in the FC++ manual.

In any case, if you decide you need it, you can still download youreself; Boost isn't stopping you.

So a Devil's advocate could argue for scrapping Boost components and rewriting them more cleanly under C++ with FC++ as a DSL -- i.e., a MP language.

That's really up to the individual maintainers of the libraries. Boost also discourages coupling, for obvious reasons.

That MP power could define exactly the right path to cool, new Boost libraries ad infinitum.

Like? If someone comes up with one and needs FC++, that will be considered in the next review period.

Maybe FC++ seems difficult to break up because it makes too much sense to keep together. Maybe Boost, not FC++, has been doing things wrongly all along.

Maybe I shouldn't have to include a 60k header file to use "flip". Maybe you should consider the arguments agains monolithic libraries before dismissing them. Maybe you should actually read the mails from the review period.

The question may have arisen during review: How might Boost components appear if built on top of C++/FC++? I suspect the answer is that they would be clean, polished, smaller, and easier to maintain. That statement I base on my own experience in MP. The statement is merely a straw-man, meant for attack.

Straw man arguments are annoying. I'm not going to go spend my time digging up evidence to refute the arguments of someone who admits he has none. Read some of the background (The boost library recommendations, some boost library code, the FC++ debate), and then we can have an informed discussion.

Last post

I don't see how that contradicts what I said.

The contradiction is between your

there was just one person...who doubted the benefits [of FP]

and their

I found it disturbing that during the review a number of traditional / imperative-style C++ programmers were just not "getting it" about FP.

I take their comment as normative, that's all.

The Boost folk don't "puzzle over FP by their own admission"! At worst, some people didn't get it! A whole mess of other people did get it!

Fine. The Boost article found it disturbing and required the author to establish some of the merits of the functional programming paradigm and even at this date is not convinced that we should have asked him...i.e. still wondering, then. Make of it what you will. The more they understand FP, the happier it makes me.

the monolithic issue has nothing to do with FP or MP, it has to do with [blah blah]...Don't call out Boost bias without considering the evidence....Maybe you should consider the arguments against monolithic libraries before dismissing them.

I did not dismiss them, I merely added a counterweight. The monolithic issue touches the subject of coherence. If a library is designed to implement FP, then maybe it ruins the design to break it into pieces. Maybe, not certainly. I have already said that the monolithic charge may indeed stick.

In any case Jim, don't overreact to my comments, qualified and tentative as they are. I am only raising possibilities, not levelling charges, and I was clear about that. I like Boost and FC++. Their overlaps may not be coincidental, was my point.

it is not a good idea to break existing code

The straw-man is rhetorical. The questions are more philosophical than tactical. Indeed, Boost says of FC++:

I would like to acknowledge its authors for the influence this library has had on other boost components. I strongly encourage you to keep working to bring the innovations from FC++ into boost in the future.

So Boost wants more, er, FC++ components in the future, no matter what I may think. If Boost is pursuing FP without knowing it, then future Boost components might not end up properly factored. Whereas the FP backdrop might actually lead to more and better factorizations, having sound theoretical properties, not just a sense of smallness. Knowledge of natural theoretical fault lines helps factorization. All I'm saying is that it may help Boost to ask these questions. C++ has not enjoyed a tradition of theoretical soundness or clean design.

Formatting

Hm, that is some interesting formatting. How did you obtain it?

In the HTML code I see stuff like:

style="font-size: normal; font-style: italic; color: green"

but I assume you didn't type all that in yourself and that Drupal emitted it.

Re: Formatting

Here you go.

Boost FC++ Review

Disclosure: I was one of the reviewers for FC++'s adoption into Boost and Mat Marcus, who led the review, is a friend. Further disclosure: I've been a Lisper since the mid 1980s, an MLer for about five years, an O'Camler for about three, and know enough Haskell to be dangerous.

I voted against FC++'s adoption into Boost.

My comments are that FC++ as revised by McNamara for potential adoption into Boost was still too monolithic (a 60K header file has already been alluded to), but that's a relatively minor quibble. The considerably greater point is that Boost already has Lambda and, hidden somewhat beneath the covers of the Spirit parser generator framework, Phoenix. It's bad enough that Boost already has two functional programming libraries—sufficiently bad that Lambda and Phoenix are in the process of being unififed and integrated. The one feature that FC++ 1.5 (which is not quite the same as what was submitted to Boost) would have brought to the table that Lambda and Phoenix do not is monads, and McNamara acknowledged that monads in FC++ were not yet ready for prime time. So I voted no, with the strong caveat to Mat that it needed to be made clear to McNamara that we remained keenly interested in FC++'s innovations and how they could be brought to Boost, most probably by way of collaboration with the Lambda/Phoenix integration effort. Joel de Guzman, Spirit/Phoenix' author, indicated a strong personal interest in working with McNamara, observing that Phoenix had been strongly influenced by FC++, as anyone who's read the Phoenix documentation already knew.

So although my vote is only one data point, it hopefully sheds some light on the question of whether the Boost reviewers simply "didn't get FP and didn't want to taint C++ with it," or whether "Boost" and FC++ overlap 100% (the latter is rather obviously false to anyone who's actually looked at Boost). Instead, I can assure you that I and the other reviewers gave full consideration to FC++'s place within Boost, both with an eye towards Boost coding/documentation standards and towards how FC++ might relate to Lambda and Phoenix. And again on a personal note, I do sincerely hope that Lambda, Phoenix, and FC++ all participate in a unification effort so that Boost has a single, consistent framework for supporting functional programming in C++.

Thanks Paul

Paul - It so happens I was looking at the Boost Spirit Phoenix preface tonight and thought it merited a link here. Upon arrival I find your comments too, and thank you for them. They do clear things up about the substantial overlap. Indeed the Phoenix stuff is hidden somewhat - I had never seen it.

No one made those statements of yours in quotes. I raised the MP and monolith issues. The official Boost announcement raised, in its own voice, conceptual merit and pedagogy issues regarding FP (and MP), whatever individual FP experts may grace Boost circles. The monolith question touches language design. If Boost offers FP, how should it break down? Or should it? Or can it? These are language design questions, as you surely appreciate. The problem is that relatively minor development issues seemingly overshadow the all-important FP language design.

One has to be careful. As CS graduate student Eray Ozkural quips, The difference between Wirth and Stroustroup? The former is a language designer. Then we have people complaining that even Larry Wall doesn't believe in language specifications. Turning to Boost,

Such a state of affairs (monolith with substantial overlap) could conceivably be acceptable if there were clear problems for which FC++ was a uniquely suited practical solution. Exact Reals (see footnote *** below) notwithstanding, I don't believe that the *practical* value of FC++ as a *monolithic* embedded DSL in C++ supporting mixed paradigm programming has been satisfactorily established.

[footnote ***: The existence of clients such as the Exact Real lib help demonstrate some degree of practicality. During the review I briefly examined the Exact Real site. This looked like an interesting application though I could not yet say how much practicality was demonstrated since, for example, the performance characteristics of lazy lists and constructive reals were not immediately clear to me. If FC++ is to be accepted on practical grounds potential users may want to be able to understand performance characteristics.]

If the authors were to break FC++ into smaller pieces and should they participate in a future lambda, phoenix, FC++ merger then the above concerns would be addressed. It surely doesn't hurt that the authors of those other libraries expressed strong interest in the above direction. And as was pointed out in the review some of the ideas from FC++ might successfully be applied to other boost libraries such as function and/or bind. If FC++ was part of a single consistent set of FP components within boost then there would be good odds of achieving consensus to accept.

Calling FP an embedded DSL is mistaken, since FP is general purpose. Come to that, many FP languages are implemented in C/C++. The Boost FP library will just be one more. Merger of code is fine, and I am all for it, so long as the idea of smaller pieces follows language-theoretic fault lines, not mere historical happenstance, legacy code issues, etc. The review proposed a set of FP components within boost rather than a straight FP language implementation, which would be too, ah, monolithic. The real question then revolves around language orthogonality, not mere development happenstance. The question of why one even wants a FP language seemed lost on the reviewer (even if not you personally). Quibbling over lack of performance metrics is missing the point. The value of mixed paradigm programming even Bjarne Stroustroup advocates. He says that Some of the more effective functional programming techniques were part of the inspiration of the STL and the use of function objects in C++. Maybe the Boost FP library will complete the vision?

The Boost FP merger project is great news. For the record, I agree with you that Boost should offer a single FP package. My only input is that it follow a clear specification, not the sort of ad-hoc, barnacle-upon-barnacle methodology of C++ evolution. That's what scared me in the summary review. So maybe Boost code ought to change as much as FC++ code, in order to define a clean FP language. Otherwise you have the barnacle method, just because one library had historical precedence, not because the language design argues for it. The statement that Boost gave full consideration to FC++'s place within Boost, both with an eye towards Boost coding/documentation standards and towards how FC++ might relate to Lambda and Phoenix offers a picture of Lambda and Phoenix resting in cement. Well, the overall FP language design should determine that. An abstract language design is really the first point of consensus. I'm sure the guys are hashing one out.

Please keep the Boost-announce mailing list up-to-date. It missed the FC++ decision, which now seems a mere formality along the way to incorporation, if Phoenix has not largely accomplished the deed already, heavily influenced as it was by FC++. It appears that Phoenix is doing bang-up work.

I share the announcement's hope that some of the ideas from FC++ might successfully be applied to other boost libraries. That statement touches on my opinion of the value of multiparadigm programming in this context, that the best way to boost C++ is to enable MP facilities. A true FP language available inside C++ would be a real boost for industrial software engineers as well as present and future Boost library authors.

(Those interested may compare with Felix.)

I realize this thread is over

I realize this thread is over a year old, but I would like to add a few comments as a reasonably long-time Boost participant and observer of the FC++ review. First, FC++ *is* a DSL, because of the very nature of C++. C++ is awesome because of operator overloading and compile-time metaprogramming. It is lacking because the runtime domain and compile-time domain are spelled differently. Some people consider that a virtue. When looking at template metacode that tries to do something serious (like FC++ does), I don't see how you can say that with a straight face. FC++ code does not look anything like vanilla C++, nor should it. It's no different than Spirit code in that regard. The cool thing is that you can do it at all.

Second, the Boost community is not full of lunkheads who are clueless about FP. I think FC++ got a fair review; and even though I personally voted in favor of inclusion, I was not entirely surprised when it was rejected. Note that it was not rejected on its overall merit, which was more or less universally recognized. Nor was it rejected on the merits of FP as a paradigm, or the lack thereof. It was rejected on technical points of the Boost philosophy which exist to maintain a high level of quality that ensures confidence in the Boost brand. Unless you are a hardcore C++ library author, it may not be obvious why Boost is picky about the way it accepts libraries; but the fact that you will find very few complaints about Boost libraries in general (and quite a few praises) should indicate that it is a mostly sound process.

Third, part of the reason FC++ did not succeed is because C++ is simply not capable of supporting FP in a satisfactory way. It is indeed an MP language, but FP is not one of the Ps. It must be left to a future, more powerful, more advanced language that has a greater conceptual purity to unify the paradigms in a natural and convincing way. The fact is, FC++ should not exist at all. In the language that replaces C++, support for FP will be intrinsic, not bolted on. And I'm afraid that Felix is most likely not that language (though it has its own merits).

functional programming in Java with generics

Mark Zander of LANL published an article in DDJ about using generics to do functional programming in Java.

For example, to implement the following function

twice :: (a->a)->a->a
twice f z = f(f(z))

... you would write the following in Java

public class Twice<A> extends Function.O2<Fcn<A, A>, A, A> {
    public A call(Fcn<A, A> f, A z) {
        return f.x(f.x(z));
    }
}

One of the reasons why Zander's implementation is better than Apache's Commons Functor library is because his approach provides type safety whereas Apache's does not.

Delegates

The dodgy multicast semantics of delegates in C# is unfortunate but thankfully you can still use them like plain old closures.

delegate T Function<T>(T arg);
static Function<T> Twice<T>(Function<T> func)
{
    return delegate(T arg) { return func(func(arg)); };
}