Stable Public Java API

Clojure does not currently provide a stable public Java API. This makes calling Clojure code from Java more verbose and more complicated than it needs to be, and requires developers to refer to classes that are actually just details of Clojure's current implementation.

A public Java API probably only needs to be a single class providing a small set of static utility methods, primarily intended to smooth the path for calling Clojure functions from Java. Off the top of my head, this might be an initial set of such methods:

In addition, some data-related methods would be helpful:

As long as we are careful with our naming, all of these methods could be statically imported in Java files, making a lot of common interop tasks much less verbose.

IFn.invoke throws Exception :-(

Because clojure.lang.IFn.invoke throws Exception, calling Clojure functions in Java (via IFn or resolved vars) implies a lot of checked exception pain. Without some solution to this, the public API for Java would also bubble up that pain through any call method or .invoke calls made using Var or IFn obtained through that API.

Potential solutions

Wrap IFn with a delegate that catches Exception and rethrows them as RuntimeException. An example of this is SafeFn.java, which allows nREPL connection functions to be used from Java with a minimum of exception management pain. The public Java API would presumably perform this wrapping automatically when making calls or when returning a function or var that will be {{.invoke}}d later.

Alternatively, drop the throws Exception declaration from IFn.invoke entirely, and change function code generation to catch Exception and rethrow them as RuntimeException. That would simplify the Java interaction, not force the introduction of one or two new classes, and avoid any wrapping inefficiencies, but I don't yet know what the repercussions would be to the compiler to effect this change or what the perf impact would be (either at runtime or compile/load time given the additional heft of each new function class).