At the moment, I have a completely functional Clojure library which is called from Java.
The way I do this : I have a file that uses gen-class to wrap the entire API as static methods of a single class and passes data in and out in the form of IPersistentVector and IPersistentMap.
Now, however, I'm refactoring the library and putting the functionality behind various Protocols.
I have four protocols, lets call them A, B, C and D. And two defrecords, X and Y. X and Y both implement protocols A, B and C. While Y also implements D.
What do I need to do to make these available to Java? Are these automatically available as Interfaces and Classes? Or do I still have to do the equivalent of the gen-class to make them public?
If not, what is the equivalent of the gen-class :methods clause, where I define the Java types for the arguments to the methods?
Does anyone have a simple example of making Protocols and records available to Java?
defprotocol
Every Clojure protocol is also a Java interface with the same name and methods. If I take an example from ibm developerworks, we see that :
Is equivalent to :
Clojure.org also has some (rather terse) information on this.
definterface
If you are aiming at performance, you could consider using
definterface
, which use is similar to the protocols. This SO post also has details about how to use it :definterface
seem to be faster than protocols.defrecord
Similarly,
record
s (as well asdeftype
anddefinterface
) will generate Java Classes. Again, Clojure.org/datatypes has useful information (emphasis mine) :So yes if will be available from Java. Just be careful with naming.
As a side note, you may want to have a look at calling Clojure from Java.