Does Scala 2.9.1 throw away type parameter information?

I am writing Java code that depends on some Scala code (which I also wrote). Trying to provide an argument with a parameterized type seems to work if Scala compiled with 2.8.0, but fails if I use 2.9.1.

Scala's (simplified) code looks something like this:

package test import collection.JavaConversions._ class SomeClass { def foo(numbers: java.util.Set[Long]) { numbers.foreach(println(_)) } } 

This compiles with compilers 2.8.0 and 2.9.1. Java code looks something like this:

 package test; import java.util.Arrays; import java.util.HashSet; import java.util.Set; public class App { public static void main(String[] args) { new SomeClass().foo(new HashSet<Long>(Arrays.asList(1L, 2L, 3L))); } } 

If I compile Scala with the 2.8.0 compiler, then Java will compile (with the Java 1.6.0_26 compiler). However, if I compile Scala with 2.9.1, then the Java compiler will fail:

 test\App.java:16: foo(java.util.Set<java.lang.Object>) in test.SomeClass cannot be applied to (java.util.HashSet<java.lang.Long>) sc.foo(new HashSet<Long>(Arrays.asList(1L, 2L, 3L))); ^ 1 error 

Thus, it seems that although Scala 2.8.0 stores information in the byte encoder that numbers is of type Set<Long> , the compiler 2.9.1 emits a bytecode where numbers is Set<Object> .

This is mistake? Is this a bad (for me) side effect of an intentional change? (Scala changelog mentions "various fixes in ... JavaConversions for smoother interaction"). If so, can I do something to make this work with 2.9.1?

+4
source share
2 answers

Good, since my shot in the dark in the comment turned out to be successful, as well as the answer.

He works with

 def foo(numbers: java.util.Set[java.lang.Long]) 

java.lang.Long does not match Long of scala. It is noteworthy that Set[java.lang.Long] may contain null , and Set[Long] should not (unless the type system was bypassed by some uncontrolled execution). This is despite the fact that Set is implemented as containing links in both cases; in the second case, they are guaranteed to be non-zero.

The identification of Set[Long] and Set[java.lang.Long] opens a loophole in the type system. However, I do not know if the change was intended.

+2
source

The short answer is complicated. Any on a system like Scala is a great unifier, but it's fantastic at the time you are in Java-land.

A simplified look made before 2.9 was poorly thought out and broke things.

To feel the rock-and-hard nature of the problem, read the Paul Phillips accounts on the mailing lists:

http://www.scala-lang.org/node/9157

http://www.scala-lang.org/node/8888

http://www.scala-lang.org/node/8980

+2
source

All Articles