People who run into me are always asking me "Are you going to rewrite
Tapestry in Scala?  Or Clojure?"  Well, I'm not going to be rewriting
Tapestry at this point, just improving it in place.

However, I do want to do some more work with Clojure; I'm really
excited by http://datomic.com/ for example, and the best way to
leverage Datomic is, in my not very informed honest opinion, to use
Clojure code to interface with the Datomic APIs.

To that end, I've wanted to make it easy to combine Tapestry view
logic with Clojure service logic.

The challenge is that, to Java code, the Clojure space is basically a
giant collection of objects all implementing the IFn interface;  it's
not clear what to inject or how to represent it in a meaningful way to
Tapestry.  Sure I could whip something together that would allow you
to inject a function as IFn and you could call one of its many
overloaded invoke() methods, but that doesn't feel right.

Instead, the new alpha tapestry-clojure library (in the master branch)
lets you do the following:

Define an interface

Map the interface to a Clojure namespace:  simply add the @Namespace annotation

Build a proxy so that each method invokes a Clojure function

Each method name is mapped to a Clojure function in the namespace. It
converts camel case to inline dashes .. thus a method named
"updateDatastore" will be mapped to a function named
"update-datastore".  If that's not sufficient, or you want to expose a
function from elsewhere, the @FunctionName annotation can be used on a
method to provide its specific name, or even a fully qualified name in
another namespace.

The ClojureBuilder service can be injected; it has a single method:

  <T> T build(Class<T> interfaceType)

The interface must have the @Namespace annotation. All of the methods
must have non-void return types.

You'll typically use it in a service builder method of a module:

  public static DatastoreAPI buildDatastoreAPI(ClojureBuilder builder)
{ return builder.build(DataStoreAPI.class); }

That's it ... DatastoreAPI is now a service like any other, and can be
injected into any service, page, component, or whatever.

Currently, this in in 5.4, which is very early alpha.

The code for this is very small, and could easily be ported back to
5.3, for 5.3.4.  Any interest?

-- 
Howard M. Lewis Ship

Creator of Apache Tapestry

The source for Tapestry training, mentoring and support. Contact me to
learn how I can get you up and productive in Tapestry fast!

(971) 678-5210
http://howardlewisship.com

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
For additional commands, e-mail: users-h...@tapestry.apache.org

Reply via email to