Thursday, July 31, 2008

Progress in Functional Java

I have been happy lately to see the progress in Functional Java. A project truly arrives when it becomes the inspiration for other clever ideas. Witness Lazy Error Handling in Java, Part 1: The Thrower Functor.

Every few days comes another fun bit of functional programming creeping its way in to my workaday language, Java. Current wish list item: the fj team deploys to a public Maven repository so I can just say:

<dependency>
    <groupId>fj</groupId>
    <artifactId>functionaljava</artifactId>
    <version>2.8</version>
</dependency>

UPDATE: This just gets more interesting: Lazy Error Handling in Java, Part 2: Thrower is a Monad and Lazy Error Handling in Java, Part 3: Throwing Away Throws.

Thursday, July 10, 2008

Guice, main and startup configuration flags

Here is a small trick we use in an in-house program wired with Google Guice. The goal is to pick the wiring configuration from the command-line without too many contortions.

The idea is to use enums to represent the wiring, and using the command-line to pick the enum. Thus:

enum WhichOne {
   /** Uses module "A", defined elsewhere. */
   ONE(new ModuleA()),
   /** Uses module "A" and "B", defined elsewhere. */
   TWO(new ModuleA(), new ModuleB());

   private final Module module;

   WhichOne(final Module... modules) {
       module = new CompoundModule(modules);
   }

   public Module getModule() {
       return module;
   }
}

class CompoundModule extends AbstractModule {
   private final Module[] modules;

   CompoundModule(final Module... modules) {
       this.modules = modules;
   }

   @Override
   public void configure() {
       for (final Module module : modules)
           install(module);
   }
}

class Main {
    public static void main(final String... arguments) {
        // Real programs use args4j
        final WhichOne whichOne = WhichOne.valueOf(arguments[0]);
        final Module module = whichOne.getModule();
        final Injector injector = Guice.createInjector(module);

        injector.createInstance(MyProgram.class);
   }
}

Now I can pick configuration on the command line:

$ my_program ONE # use module "A"
$ my_program TWO # use module "A" and "B"