Joel has a fascinating recent post on functional vs. OO programming [1], which I found thanks to a comment from Danto a recent dev.* post [2].
What I found so interesting about this post is that it advocates and speaks to the power of an approach that I had long ago dismissed as sloppy or even frightening--the passing of free-floating functions as method/function arguments.
At the bottom of the post, he links to an amusing takedown of Java as an overly-rigid OO language. The overall point seems to be that functional programming is powerful and leads to ways of thinking that OO does not. I can't speak to the affect of one programming language or another on the way people think, but I can give my impressions of the funtional aspects of what I call free-floating functions.
What I mean by a free-floating function is a function that is not tied to a class. For example:
doSomething(thingToDo);
as opposed to
ThingDoer.doSomething(thingToDo);
The thing I've never liked about languages that allow free-floating functions is that they lead to sloppiness and confusion. Where does the magic non-name-spaced function exist? How can I access it? What do I need to import/include to get to it? What happens if there are different doSomething() funcions I want to use?
To my mind, Java and other OO languages provide a simple means of organizing functions as static methods that reside in an un-instantiatable object. The benefit you get with this approach is namespacing. The drawback is a slightly longer call. Is that really such a big deal?
What Joel describes as particularly powerful is the ability to pass a function as an argument, even one created on the fly in-line. He asks if my programming language can do this. Well, my language is Java and the answer is yes and no.
No, you can't pass a function as an argument nor create one inline. But, yes, you can accomplish anything this practice can accoplish--you just have to use slightly different means. And, actually, I think the result is Java is more readable and maintainable than the result you'd get with a free-floating function.
To pass a "function" to a method in Java, all you need to do is make the function part of an class and pass an instance of that object. This is trivial for any Java programmer and most Java programmers do this sort of thing every day.
In fact, I can easily implement Joel's map() function in Java.
public interface ThingToDo {
public int doThingToInteger(int i);
}
public class Mapper {
//Makes it so you can't instantiate this class.
private Mapper(){}
public static void map(ThingToDo doer, int[] intArray) {
for (int i = 0; i < intArray.length; i++) {
intArray[i] = doer.doThingToInteger(intArray[i]);
}
}
}
//And then somewhere in a method we'll have this line:
Mapper.map(new ThingToDo() { public int doThingToInteger(int i) {return i*2;}; }, a);This is a trivial example (as Joel himself says), and yes, the inline class creation is ugly, though I would argue, not so much less ugly than inline function creation. A better practice would be to create the specific ThingToDo implementation as a separate .java file. Some would call this sort of thing clutter. I simply call it organization.
What the OO solution to this problem gives you, though, is some nice name-spacing, the potential for type safety in your map method and a potentially much more readable batch of code. What's the major issue with this?
I'll also admit that I'd never thought of farming looping itself off to a utility method. That's a terrific idea for all the reasons Joel argues. I'm just saying that there's no reason this can't be done in an OO language as easily as in a functional language.