Is there anyway to call Clojure macros from Java?
Here is what I am trying to do:
RT.var("clojure.core", "require").invoke(Symbol.create("clojure.contrib.prxml"));
Var prxml = RT.var("clojure.contrib.prxml", "prxml");
Var withOutStr = RT.var("clojure.core", "with-out-str");
String stringXML = (String) withOutStr.invoke((prxml.invoke("[:Name \"Bob\"]")));
prxml writes to *out* by default which is why I need to wrap it with the macro with-out-str which returns the string.
I am getting this error:
[java] java.lang.IllegalArgumentException: Wrong number of args (1) passed to: core$with-out-str
[java] at clojure.lang.AFn.throwArity(AFn.java:437)
[java] at clojure.lang.RestFn.invoke(RestFn.java:412)
[java] at clojure.lang.Var.invoke(Var.java:365)
[java] at JavaClojure.xml.main(Unknown Source)
You'll have to roll your own withOutStr.
class YourClass {
static final Var withBindings = RT.var("clojure.core", "with-bindings*");
static final Var list = RT.var("clojure.core", "list*");
static final Var out = RT.var("clojure.core", "*out*");
static final Var prxml = RT.var("clojure.contrib.prxml", "prxml");
static String withOutStr(IFn f, Object args...) {
StringWriter wtr = new StringWriter();
withBindings.applyTo(list.invoke(RT.map(out, wtr), f, args));
return wtr.toString();
}
...
String stringXML = withOutStr(prxml, "[:Name \"Bob\"]");
}
The problem is basic.
invoke (and its sister, apply) are used for functions.
Macros are not functions, so they can not be invoked. Macros need to be compiled. In normal Lisps, they could just be eval'd or macroexpanded or whatever. And in 10m of looking around, apparently Clojure doesn't have a simple RT.eval(String script) function to make this easy.
But, that's what needs to be done. You need to compile and execute this.
I saw a package that integrates Clojure with Java JSR 223, and IT has an eval (because 223 has an eval). But I don't know a) if the package is any good or b) if this is the direction you want to go.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With