views:

116

answers:

2

I would like to embed Clojure code into Java. This site was helpful in the basics of setting this up, but the only arg it ever passes is of type String. I have tried using ints as well, and those also work.

My question is whether there is some formatted way to pass in structured data to Clojure. In particular, I have a list of points I would like to pass to Clojure and turn into a vector that would look something like this:

[[1 2] [3 4] [5 6]]

What is the easiest way to go about doing this? Is there preprocessing I can do on Java's end, or should I do postprocessing on Clojure's end, or is there something in Clojure that will handle this? I suspect it's passing in a String of numbers and the length of each tuple to Clojure, and letting it process the String into a vector. However, this aspect of Clojure doesn't have many examples, and I'm curious if I'm missing something obvious.

EDIT: Please look at mikera's answer is you're interested in passing in Java Objects. Please look at my answer below if you just want to format your data ahead of time into a Clojure format for a set/map/etc.

+2  A: 

It depends a bit on what format your data is in to start with, but you may find it easiest just to pass the Java object that represents the data directly and read it using Clojure's Java interoperability features.

e.g. you could pass a Java array of Points directly and do something like:

(let [point (aget some-array index)]
  (do-stuff-with-point point))
mikera
Well, I'm not entirely sure what format I'll end up wanting - it's mostly just exploratory right now. Your solution definitely will work best with Objects.
allie
+1  A: 

For those cases when you want to pass in a simple data structure that you've already formatted to look like Clojure in Java, you can pass in that arg as a string. So for the example I gave in my question, I would pass in

"[[1 2] [3 4] [5 6]]"

as my arg. When you've called Clojure using invoke(arg), you can make the first step of your function to be a call to readString on your arg:

(defn foo [d]
  (def data (read-string d)))

The above will produce a vector when the example String is passed in.

allie