1
votes

I have a Maven project where I mix java and Clojure code with the help of the clojure-maven-plugin.

I have a Clojure namespace like this:

(ns org.myproject.clojure
    (:gen-class))

(defn do-stuff [] (println "Doing stuff"))

And from java, I call it like:

IFn require = Clojure.var("clojure.core", "require");
require.invoke(Clojure.read("org.myproject.clojure"));
IFn do_stuff = Clojure.var("org.myproject.clojure", "do-stuff");
do_stuff.invoke();

When running this code, "Doing stuff" is correctly being printed to the screen. Moreover, I can see .class files for my clojure code inside the generated jar from maven. Despite all that, I'm still not sure what's clojure doing when I require the namespace. Is it compiling the whole thing all over again? Or is my code being properly AOT compiled with my setup?

Finally, is there a way I can treat my clojure code as "regular" java functions? That is, importing org.myproject.clojure and calling do-stuff as a regular function? Given that clojure is generating bytecode for my code. I don't see why java couldn't call it being bytecode compatible.

1
I don't know enough to answer your question, but this may be helpful.Aaron Harris

1 Answers

1
votes

Require does not compile your code, it loads the necessary classes dynamically. Your code is already compiled, unless of course you call compile yourself on another file.

Second, you cannot use Clojure functions as Java functions, because they are not the same thing. As you can see, Clojure functions are objects that implements IFn and have invoke methods. I don't think using directly Java methods would be feasible: you have to call methods on classes or instances, but which objects owns the methods? Further, using objects to implement functions means that they are truly first-class and that you can easily change bindings at runtime, which is what dynamicity is about.