简体   繁体   中英

How to both declare a Clojure function and immediately run from Java code using the clojure-utils?

I want to declare a Clojure function and instantly evaluate it in the Java code using clojure-utils. How to do this?

The code I'm using is this:

public static void main(String[] args) {

    String s = "(defn fun[lst] (map #(/ % 2) lst))" +
               "(list* (#'clojure.core/fun '(1 2 3 4 5)))";
    System.out.println("Evaluating Clojure code: " + s);
    Object result = mikera.cljutils.Clojure.eval(s);
    System.out.println("=> " + result);
}

If I just use the following expression in the string variable s , it will work fine:

(list* (map #(/ % 2) '(1 2 3 4 5)))

And the Java Compiler will show:

=> (1/2 1 3/2 2 5/2)

But if I try to both declare my function and then try to call it from the code, like this:

String s = "(defn fun[lst] (map #(/ % 2) lst))" 
         + "(list* (fun '(1 2 3 4 5)))";

The Compiler will only show this:

Evaluating Clojure code:

(defn fun[lst] (map #(/ % 2) lst))(list* (#'clojure.core/fun '(1 2 3 4 5)))
=> #'clojure.core/fun

UPDATE: I wrote this construction, it's awful, but it works:

String s = 
"(do 
    (defn main[lst]

      (defn fun[lst]
        (map #(/ % 2) lst))

      (list* (fun lst))) 

    (main '(1 2 3 4 5)))"

Result: => (1/2 1 3/2 2 5/2)

UPDATE 2 (Fixed):

(do 
    (defn fun[lst]
        (map #(/ % 2) lst))

    (list* (fun '(1 2 3 4 5))))

It is not a REPL, so it will only read one s-expression and evaluate it. You should eval every one.

public static void main(String[] args) {
    clojure("(defn fun[lst] (map #(/ % 2) lst))");
    clojure("(list* (#'clojure.core/fun '(1 2 3 4 5)))");
}

public static Object clojure(String s) {
    System.out.println("Evaluating Clojure code: " + s);
    Object result = mikera.cljutils.Clojure.eval(s);
    System.out.println("=> " + result);
    return result;
}

You are just using a String evaluation. But it's more obvious to directly use interoperation with Clojure.

For example you could use load-string function :

IFn loadString = Clojure.var("clojure.core", "load-string");
Object result = loadString.invoke("(println \"Appel\")(your clojure code)");

On interoperability : http://clojure.github.io/clojure/javadoc/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM