2
votes

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)
2
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)? - Beryllium
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. - Rafał Dowgird
@Berrylium Yeah basically those. Thanks I updated the question. - Jeroen van Dijk
@RafałDowgird I'm puzzled too, but the Java code is able to run locally. - Jeroen van Dijk
@JeroenvanDijk Tried to reproduce it in an online Java compiler and failed. See my answer for details. - Rafał Dowgird

2 Answers

3
votes

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);

 }
}
0
votes

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])