Feb 26

Functors are defined as a function encapsulated in an object. In most cases, the function’s parameters can be set and the result retrieved using the common accessor pattern, such as setParameter1(Object value) or getResult(). The fact that these functions are encapsulated by real objects is also the reason for its greatest benefit: the use of many design patterns including structural ones such as the Decorator pattern and behavioral ones such as the Visitor pattern.

Functors in software design

While the classic object oriented design encourages inheritance and method overloading to achieve code reuse and code specialization, the functors’ design promote another approach, of composition. Functors are created to accomplish simple tasks and are later connected together, by connecting one functor’s result to another’s parameter, to satisfy a greater goal of the application.

By combining different functors together, one can in fact create a proxy functor, which takes parameters for its encapsulated functors, and returns a result which is in fact the result of the last functor in its composition. As an example, take the classic genetic algorithm cycle of population initialization, evaluation, selection, breeding, evaluation again, replacement of older generation and back to selection. Each of these can be defined by a functor, and the output of each is connected as the input of the next. In fact, the main iteration (selection, breeding and evaluation) can be defined by a functor as well, and then called iteratively until the stopping condition is reached.

The best Java functors’ framework I could find out there is Java Generic Algorithms, or JGA. It offers the generic functor, and on top of that offers the three most common functors, being Generator (no parameters), UnaryFunctor (single parameter) and BinaryFunctor (two parameters). Functor composition is available through the ability to bind any parameter of a functor to any other functor or constant value. To continue our previous example, let’s composite the main GA iteration using JGA:

GA with JGA

And in code:


UnaryFunctor<Population, Individual> selector = …;
BinaryFunctor<Individual, Individual, Individual> breeder = ….;
UnaryFunctor<Individual, Individual> evaluator = …;

UnaryFunctor<Population, Individual> composedBreeder =
    breeder.compose(selector, selector);
UnaryFunctor<Population, Individual> composedEvaluator =
    evaluator.compose(breeder);

return composedEvaluator;

Later on, this generated functor can be used and composed with other functors, such as a functor to iteratively produce new offsprings for the new generation and a functor to check for the end-condition. Speaking of the end-condition functor, these special functors with a result of a boolean are sometimes referenced to as Predicates, and are more widely known and used.

Real life usages of functors

The best use for functors in an application that I have seen yet is in fact not in the Java realm, but in Apple’s Core Image framework: by creating image manipulation functions (the Image Units) and exposing their functionality as functors, this framework allows anyone to create endless image manipulations, simple or complex, with very little amount of code. In fact, Apple went the extra mile by providing an application for composing these functors together without a single line of code, called Quartz Composer (if you own a Mac, you really want to take a look at it – it’s free!)

There are two differences between the way Core Image functors and JGA functors work, though: first, it allows for multiple results in addition to multiple parameters, referenced to as input and output ports. Second, it uses named ports instead of numbered ports, which makes it somewhat easier to follow and document. As an experiment, I’ve tried implementing a functor framework more similar to the CI approach. It works, and I might publish it here soon.

Next

There’s a lot to say about functors, their different usages and some common problems one might encounter when working with them. I’ll try to cover more about this way of development later, as it allows the creation of very dynamic applications and very sophisticated frameworks.

Related Posts with Thumbnails
Share

6 Responses to “Functors in Java and beyond”

  1. ryan Says:

    Is it just me, or is this similar to function composition in Haskell?

  2. Avah Says:

    ryan: Interesting. I didn’t go into Haskell at all, but I know that many languages has a “functions as objects” feature; interesting to find that some languages actually have a function composition feature built into it.

    I’ll read more about it and see how it relates to functors and their compositions.

    Thanks!

  3. Kit Davies Says:

    Good post.
    “Functions as objects” (or more precisely “functions as first-class types”) is exactly the basis for functional programming, eg. Haskell, Lisp, Erlang et al. So yes function composition using functors is going to look similar to the same in Haskell or any FP language.
    Also possible would be supplying a single parameter to a binary functor to produce a new reusable unary functor with the parameter already “baked in”. This gives you currying.
    Also look at map/reduce. This applies “map” functors to a list to produce new lists, and “reduce” functors to the new lists to produce some kind of cumulative result for each new list. The key benefit being that given appropriate partioning of the initial list, the mapping and reducing functors can operate in parallel, hence the much vaunted scalability of the map/reduce model.
    Interestingly Scala is a language that aims to provide a combination of FP and OO on the JVM. If this is an area of interest, I suggest you look there also.
    Finally (phew) FunctionalJ is another library for doing FP in pure Java.

    Regards
    Kit

  4. Web 2.0 Announcer Says:

    Functors in Java and beyond

    [...]Functors are defined as a function encapsulated in an object. In most cases, the function’s parameters can be set and the result retrieved using the common accessor pattern, such as setParameter1(Object value) or getResult(). The fact that these…

  5. Avah Says:

    Kit: Thanks for all the information! I will take all of this into account when writing more about functors, as I have more to say about them.

  6. Paul Says:

    Great post. For some useful functors check out the commons collections project. It has a functors package with includes Predicates, Closures, and Transformers. http://commons.apache.org/collections/api-release/org/apache/commons/collections/functors/package-summary.html