2

I was specifically trying to test Cjoures's claim that it can work with Java "seamlessly". In general, how do you translate Java code:

object1.object2(some_args).object3.object4(some_other_args).object5.objectnth.method(arg‌​1, arg2, argn);

to Clojure? Some of the objects in the chain maybe static classes, static methods or class variables, some are interfaces. It just doesn't seem straightforward. E.g., the objects in the graphics library. I recall that at one time I tried to create an object (Graphics.) and Clojure said it didn't know that class Graphics.

4
  • 2
    Do you have a concrete example? The above sample is a bit vague. You could start by looking at clojuredocs.org/clojure.core/doto for one example. Also please see clojure-doc.org/articles/language/interop.html Commented Aug 18, 2016 at 19:36
  • "Some of the objects in the chain maybe static classes" No. Commented Aug 18, 2016 at 19:37
  • @AlanThompson Actually, .. would be more suitable in this case. Commented Aug 18, 2016 at 19:38
  • 2
    If Clojure didn't "know" about a class that's a classpath issue. It's not magic (mostly), and its Java interoperability is well-documented. Do you have a specific issue or example? Commented Aug 18, 2016 at 19:44

1 Answer 1

2

Lets take a java example:

public class Test {

    public Test a;

    public Test getA() {
        return this.a;
    }

    public Test add(Test a) {
        this.a = a;
        return this;
    }

    public int foo(int a, int b, int c) {
        return a+b+c;
    }

    public long foovar(Long... ai) {
        long r = 0;
        for (long i:ai) r+= i;
        return r;
    }
}

And show a bunch of ways to access internal objects:

(import 'Test)

;; create all the objects
(def t1 (Test.))
(def t2 (Test.))
(def t3 (Test.))
(def t4 (Test.))
(def t5 (Test.))
(def t6 (Test.))

;; and lets chain them together:
(.add t1 (.add t2 (.add t3 (.add t4 (.add t5 t6)))))

;; verify using member access:
(= t6 (.. t1 a a a a a))  ;; true

;; verify using method call:
(= t6 (.. t1 getA getA getA getA getA)) ;; true

;; and mixed access
(= t6 (.. t1 a a getA a a))  ;; true

;; lets invoke foo:
(.. t1 getA getA getA getA getA (foo 1 2 3)) ;; 6

;; and invoke foovar:
(.. t1 getA getA getA getA getA (foovar (into-array[1 2 3]))) ;; 6

Now we can also create helper functions:

;; get the object at depth n using functions
(defn get-nth-function [o n]
  (first (drop n (iterate (memfn getA) o))))

;; get the object at depth n using member access.
;; This same notation could also be used for function,
;; however I just wanted to show an example of memfn
(defn get-nth-member [o n]
  (first (drop n (iterate #(.a %) o))))

;; lets verify:
(= t6 (get-nth-member t1 5)) ;; true

;; lets invoke foovar on object position 6, 
;; on a range of numbers from 1 to 10
(.foovar (get-nth t1 5) (into-array (range 10))) ;; 45

This should shows the flexibility of interacting between clojure and java. When you have static members, you could access them with / as you did for System/out (although . works too). Please be sure to fully read http://clojure-doc.org/articles/language/interop.html and if you still dont get something, let us know.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much !!! Trust me; I have read java-clojure interop from the clojure official site multiple times. It is great that I can get some answers from people like you who are generous with giving out knowledge instead of just telling me to RTFM . Thanks again !

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.