2

I'm trying to port some Java code to Clojure and I ran into a situation that I can't solve.

Normally when you want call a Java constructor or method with a variable length argument you do something like this

(Fields. (into-array Comparable ["predict", "other"]))

However I found a special example where this doesn't work:

(Fields. (into-array Comparable ["predict", Double]))

Although this seems possible in Java (see below), the code above gives the following error:

IllegalArgumentException array element type mismatch  java.lang.reflect.Array.set (Array.java:-2)

I tried a couple of variations, but nothing seems to work. The Java code I try to port (and the specific line that gives trouble) is here https://github.com/Cascading/pattern/blob/wip-1.0/pattern-examples/src/main/java/cascading/pattern/Main.java#L76

new Fields( "predict", Double.class )

(The constructor signature for Fields is Fields(Comparable... fields) http://docs.cascading.org/cascading/2.1/javadoc/cascading/tuple/Fields.html#Fields(java.lang.Comparable...)

I tried the following examples in the Clojure repl:

(into-array Comparable [(type Double)])
(into-array Comparable [Double/TYPE])
(into-array Comparable [Double])
=>
IllegalArgumentException array element type mismatch  java.lang.reflect.Array.set (Array.java:-2)
6
  • Which variations? In the Java case the 2nd parameter is a class. I'm not fluent in Clojure, have you tried something like Double.class, Double.type, (class Double), (type Double)? Commented May 31, 2013 at 8:59
  • I'm puzzled as to why this works in Java. Double.class should be of type Class, which does not implement Comparable. Unfortunately I don't have a Java compiler at hand to check that. Commented May 31, 2013 at 9:04
  • @Berrylium Yeah basically those. Thanks I updated the question. Commented May 31, 2013 at 9:07
  • @RafałDowgird I'm puzzled too, but the Java code is able to run locally. Commented May 31, 2013 at 9:10
  • @JeroenvanDijk Tried to reproduce it in an online Java compiler and failed. See my answer for details. Commented May 31, 2013 at 9:22

2 Answers 2

3

I have tried to pass Double.class as Comparable in Java and got this:

Line: 4
foo(java.lang.Comparable...) in HelloWorld cannot be applied to (java.lang.String,java.lang.Class<java.lang.Double>)

Here's the code I tried to compile:

public class HelloWorld {
  public static void foo(Comparable... args) {}
  public static void main(String[] args) {
    foo("predict",Double.class);

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

1 Comment

Thanks @Rafal, could you try this as well: git clone [email protected]:Cascading/pattern.git; cd pattern-examples; gradle clean jar; ls build/classes/main/cascading/pattern/Main.class
0

Looking at Field class constructor code in cascading I guess you should be fine to port this specific line as:

(into-array Comparable ["predict" 0.0])

1 Comment

In the current ported code I actually have (Fields. (into-array ["predict", "1.0"])) and this doesn't give any error. My concern is that I can put any Comparable there and it doesn't break, so the Double.class variant might only be required in a specific edge case. I'll have to ask the creators of Cascading Pattern

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.