Introduction

jga is a functors library: the intent is to explore and exploit functors as a design and implementation tool to reduce boilerplate coding. A functor is an object that encapsulates a function or expression: it can take arguments and produce results, as can any method, expression, or function (in other languages that support functions). Unlike an expression, as an object it can be passed as an argument without being executed; it can be persisted to a database or file; it can be serialized and passed from client to server (and back); and it can be instantiated at runtime based on information unavailable at compile-time.

How many times have you...

Functors provide a mechanism that can reduce all of the design problems: they allow you to (in effect) pass a line of code as an argument to a constructor or method, giving you a way to parameterize objects on simple behavour.

jga borrows the functors from C++ STL library, and extends them with functors that are natural for java programmers. jga also borrows the notion that basic functors implementing common operations can be profitably combined into compound structures to implement more useful logic.

Compound functors of the type that jga promotes fall naturally into a tree structure. Taking advantage of this yields a use of functors that may be relatively new to many: as a form of executable metadata that can be interpreted for the information embodied in the structure. To facilitate this, all jga functors provide support for a Visitor implementation.

The most natural application of a functor library is in the implementation of common algorithms, such as those defined in STL. jga provides a set of such algorithms that have been adapted to java conventions and idioms, as opposed to being a direct port of STL.

An area that is rife with one line interfaces is event driven programming of the sort that is typified by Swing. jga includes the beginnings of a set of tools for use in GUI coding that addresses the common problems described above: the continual reinvention of the same set of small wheels in the set of listeners, editors, renderers, and models that accompany a typical Swing program.

jga 0.8.1 now available
Sep. 15, 2009

jga: Generic Algorithms for Java, release 0.8.1 is now available

The hilights of this release are;

  • More support for variable length Functors in the API and in JFXG. Functors now support compound forms, allowing arguments to be bound, generated, or computed by nested functors.
  • New Algorithms: Flatten (return the contents of two dimensional data structures in a single iterator), Compare (compares the contents of two data sources), and Summarize.lookup (returns the first value in a data source that meets some arbitrary criteria).
  • JFXG is now a JSR-223 compliant scripting langauge, with additional support for functors that take an arbitrary number of arguments, local variables, and assignment forms.

This release is compatable with Java 1.5 or later.

jga 0.8 now available
Dec 19, 2006

jga: Generic Algorithms for Java, release 0.8 is now available

The hilights of this release are;

  • Dual license structure: JGA can now be distributed via either the LGPL or the CDDL.
  • util reorginization: the util package is being reorganized to make it easier to find and use the algorithms in the library
  • more concise functor creation: at the suggestion of users, the vast majority of the functors in the library may now be built via static methods.

This release is compatable with either Java 1.4 or Java 1.5.

jga 0.7 now available
Apr 5, 2005

jga: Generic Algorithms for Java, release 0.7 is now available

The hilights of this release are;

  • Support for the Java 1.5.0_02
  • The new FunctorParser (and it's typesafe extension GenericParser) allow functors to be described using java-like syntax: the parser creates the functor that implements the logic described in the expression.
  • Hacker's Worksheet is the next phase in the evolution of the Spreadsheet engine included in the prior release. This application uses the FunctorParser to implement a spreadsheet whose expression langauge looks like java in most respects.

This release is compatable with either Java 1.4 or Java 1.5.

A Java Hacker's Worksheet (preview)
Dec 13, 2004

The Spreadsheet widget in the net.sf.jga.swing package grew out of a couple of design goals behind the jga library. The first was that a spreadsheet could be thought of as a sparse matrix of function objects. The second was that to really use a spreadsheet would require some language that the user could enter into the cells. A 'scripting' capability that would allow a much easier method for creating compound functors has always been on the list of goals for this project.

The parser and spreadsheet have both advanced in development now to the point where it's time to get some feedback. Neither is in its final state, yet, but both are somewhat usable. To that end, I've published an applet version of the Java Hacker's Worksheet. I'm very interested in getting some feedback on this, particularly in cases where it doesn't work in some unexpected way.

There's a javadoc extract for the expression language and the parser in their current form.

You can use the parser programatically. There's an example of building a reasonably compound formula in the jga & the java 1.5 forloop where the goal is to generate random coin flip. To build the functor programatically, you would use the following declaration.

Generator<Boolean> coinflip = 
    new LessEqual<Double>().bind2nd(0.5d).generate(new Random());
          

Using the FunctorParser (or in this case, the generified derivitive GenericParser), you would use the following declaration:

GenericParser parser = GenericParser.getInstance();
...
Generator<Boolean> coinflip = 
    parser.parseGenerator("Math.random() <= 0.5d", Boolean.class);
          

There are three main methods in the FunctorParser: one that returns a Generator, one that returns a UnaryFunctor, and one that returns a BinaryFunctor. The GenericParser contains similar methods, but each takes an extra class reference in order to check the return type of the resulting functor.

/**
 * 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;
          

jga Project Blog at JRoller
Dec 5, 2004

I've started a blog entitled "Scraps from a Messy Desk" on JRoller.com that I intend to use (at least in part) as a resource for generating documentation for jga. I've already put in a couple of entries about the project's history and motivation, and I also expect to use it as a sounding board for trying out new content that will eventually be used to improve this site.

There's a link to the blog in the header. Additionally, I'll probably be permalinking to specific entries from the documentation page when it makes sense.

Java 1.4 Compatability
Feb 17, 2004

Sun recently released the first beta version of the 1.5 JDK. I've converted this project to use the new beta: everything works as expected although the new compiler generates many more warnings than the old compiler did. However, classes compiled with 1.5 syntax may not be used with previous versions of the JDK or JRE. For a little more information, see this thread on Sun's Java forums. There was a far lengthier thread that contained more information about Sun's decision, but unfortunately, the controversy caused a few posters to generate too many flames toward Sun's developers, and the thread has been deleted.

I've decided for my own project that abandoning the 1.4 jdk is not an option, at least for now. From this point, and for as long as I can reasonably do so, I will maintain two versions of jga. From this release forward, I'll designate the version for use with the 1.4 jdk with an 'a' suffix to the version number, and the version for use with the 1.5 beta jdk with a 'b' suffix. As long as I can keep the codebase the same and simply use different build mechanisms to produce the two versions, I'll do so. If Sun introduces some new incompatable syntax during the beta period or if the effort to keep the two versions in sync becomes too great (neither of which I consider likely), then I'll have to reconsider.

With the release of the 1.5 beta compiler, I've decided to elevate the status in the SourceForge trove to 'beta'. I have considered breaking the swing package out into a separate delivery, as the 'core' part of the library (ie, the fn and util packages) is largely complete and the swing package will likely continue to grow. The justification for breaking out the swing package is that, IMO, the 'beta' level is more appropriate when the scope of the package is complete and the remaining work is bug fixes. On the other hand, with the necessity of creating a second set of deliverables to support the new 1.5 beta JDK, I didn't want the number of different jar files being downloaded to explode. For now, the swing package is still expected to grow in functionality even though the overall project is in a 'beta' phase. As before, I expect that all code in the library is stable (the earlier 'alpha' status was a reflection of expected growth everywhere in the library).

jga & the Java 1.5 forloop
May 15, 2004

One of the new features in Java 1.5 is the new forloop syntax. The new forloop is analagous to a foreach construct that is common in other languages. The syntax hides the existance of an iterator, and is even extended to cases that didn't have an iterator before (arrays). It also extends to enumerated types.

So, if hiding the iterator is a step forward, can we take things another step and capture more of the common patterns as part of the loop mechanism? The answer is 'sort of'. We can't completely hide the fact that decisions are being made, and that some elements are being processed. What we can do is hide a lot of the mechanics of the process.

System Requirements & Installation
May 10, 2004 (updated Sept 10, 2009)

jga may be used with Java 1.5 or later. The JFXG scripting langauge is usable with Java 1.6 or later, or with Java 1.5 and the separately packaged scripting API's.

If you want to use the included test framework, you'll need jUnit 3.8.1 or later, and jfcUnit 1.0.3.

To build jga from source will require ant 1.6.2 and javacc 3.2.

Installation

Installation is pretty trivial -- unpack the distribution and put either jga-0.6.jar or jga-0.6-retro.jar on your CLASSPATH.