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.

Thank you very much!

lisprog

lisprogtor
  • 5,677
  • 11
  • 17
  • 2
    Do you have a concrete example? The above sample is a bit vague. You could start by looking at http://clojuredocs.org/clojure.core/doto for one example. Also please see http://clojure-doc.org/articles/language/interop.html – Alan Thompson Aug 18 '16 at 19:36
  • "Some of the objects in the chain maybe static classes" [No.](http://stackoverflow.com/q/1215881/5044950) – Sam Estep Aug 18 '16 at 19:37
  • @AlanThompson Actually, [`..`](https://clojuredocs.org/clojure.core/_..) would be more suitable in this case. – Sam Estep Aug 18 '16 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? – Dave Newton Aug 18 '16 at 19:44

1 Answers1

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.

Shlomi
  • 4,708
  • 1
  • 23
  • 32
  • 2
    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 ! – lisprogtor Aug 18 '16 at 21:38