Writing Compound Functors
One of the reactions that I've seen to the use of the typical set of functors was that the method of combining functors into complex expressions wasn't terribly straightforward. Learning to combine the basic set of functor primitives into a useful functor is a barrier to use. It isn't that it is difficult, it is that it is a little different (at least to those of us whose background is primarily with ALGOL derivitives), and it can take a little time for the light in your head to go on.

For example, by itself, LogicalAnd isn't terribly useful as a functor. To build a predicate that returns true if a given integer is between 0 and 10, (assuming that there is no 'Between' predicate), you would generally write:

public UnaryFunctor<Integer,Boolean> uf0 =
    new ComposeUnary<Integer,Boolean,Boolean,Boolean> (
        new Bind2nd(0, new Greater.Comparable<Integer>()),
        new Bind2nd(10,  new Less.Comparable<Integer>()),
        new LogicalAnd());

Depending on your formatting habits, you would of course rearrange this to suit you, but there's no getting around the fact that the three predicates that the programmer really cares about ( > 0, < 10, And ) are buried within a fairly complicated outer constructor call.

I think the natural reaction to a constructor call like this (and they can get far, far worse) is 'GAAACK!'. It's not that hard to deal with once you get used to it, but it'll never really be good this way.

One way to get past this is to not combine it into a single ctor call:

Bind2nd<Integer,Integer,Boolean> a = 
    new Bind2nd( 0, new Greater.Comparable<Integer>());
Bind2nd<Integer,Integer,Boolean> b = 
    new Bind2nd( 10,  new Less.Comparable<Integer>());
LogicalAnd c = new LogicalAnd();
UnaryFunctor<Integer,Boolean> uf1 = 
    new ComposeUnary<Integer,Boolean,Boolean,Boolean>(a,b,c);

which scales better, but still has the disadvantage of burying the code's intent inside the distracting structural stuff. There's even more verbage describing the structural parts, so in some ways, the important stuff is even harder to get to.

It isn't hard once you get used to it, but I've also seen this exact code being used as the justification for rejecting the use of functors, due to the perception that the learning curve is so high that it just isn't worth the trouble. In jga, there are builder methods in the base class interfaces that hide the adaptor functors, so that the programmer only needs to declare the functors that implement the desired functionality.

public UnaryFunctor<Integer,Boolean> uf2 =
    new LogicalAnd().compose(new Greater.Comparable<Integer>().bind2nd(0),
                             new Less.Comparable<Integer>().bind2nd(10));

This can also be broken out into separate declarations, and probably would be for more complicated examples. The structural aspects are now hidden inside the 'compose' and 'bind2nd' methods: you can see that _something_ is going on but you don't necessarily need to know the gory details, unless you really want to.

A new option available on the HEAD release, you may write the functor's implementation in the Java-esque expression language. This is also available if you've downloaded any version of the Hacker's Worksheet or (in an older version) in my incubator area of the JDNC project. There is a run-time parser class that includes the following interface:

/**
 * Parses the string to create a Generator.
 */
public Generator parseGenerator(String str) throws ParseException;


/**
 * Parses the string to create a UnaryFunctor that takes an argument of the
 * given type.
 */
public UnaryFunctor parseUnary(String str, Class argType) 
    throws ParseException;


/**
 * Parses the string to create a BinaryFunctor that takes arguments of the
 * given types.
 */
public BinaryFunctor parseBinary(String str, Class arg1Type, Class arg2Type)
    throws ParseException;

This version of the parser returns raw functor types: this is primarily intended to support java 1.4: to use this with java 1.5, you may cast the functor to the desired type, at the risk of runtime exceptions either at the point of cast or when the functor is evaluated.

FunctorParser parser = new FunctorParser();
UnaryFunctor<Integer,Boolean> uf3 = (UnaryFunctor<Integer,Boolean>)
    parser.parseUnary("x > 0 && x < 10", Integer.class);

There is a generic extension of the Parser that adds checks for proper return types, and casts the functor to the proper genericized type (or throws ClassCastException if the expression doesn't yield the given type). You may still get the runtime exceptions, but they will be thrown at parse time, where they are already expected (and you will already have exception handling in place).

GenericParser gparser = new GenericParser();
UnaryFunctor<Integer,Boolean> uf4 = 
    gparser.parseUnary("x > 0 && x < 10", Integer.class, Boolean.class);

From here, it's not hard to imagine one more refinement. The biggest problem that I see with the current state is that parsing is done at runtime, and must account for a couple of exceptions: ParseException and ClassCastException. With the annotation mechanism built into Java 1.5, I intend to wrap the FunctorParser class inside an annotation processor, and see if we can't build the functors primarily at compile time, and figure out how to make them available at runtime. I'd like to insert the constructor code directly into the source code, but I haven't yet had the time to look at writing annotation processors to see how it can happen.