Code generation for tuples

I’m working with tuples with reflection and got a problem with:

def test(tupleParam: (Int, String)) = println(param)

Compiler (2.11.8) generates the method with signature test(Tuple[Object, String]), which makes it nearly impossible to recreate a parameter with reflection (e.g. from JSON).

Any clues?

TL;DR.What are you trying to do? My best guess is serializing with JSON a list of actions, and running them from the deserialized JSON, but I’m not sure. Probably Scala reflection (or its next generation in scala.meta) is the answer, which avoids caring about details such as this or tons of other ones.

In that tuple Int is boxed. I’m not sure why you get Object instead of java.lang.Int (others might know), but it’s somewhat sensible. But regardless of that, I expect you’re not really supposed to rely on such details (they’re not documented and subject to change), and you should usually use Scala reflection, which reads extra info in classfiles which preserves the Scala signatures. Otherwise, you’re liable to run into many other issues on any nontrivial examples.

The Java/JVM type system doesn’t allow primitive types as type parameters, so it simply isn’t possible to make the type appears to be Tuple2[Int, String] from Java reflection’s point of view.

Depending on your use scenario, using Scala reflection instead might be an option.

You might have expected Tuple2[java.lang.Integer, String] instead of Tuple2[Object, String], and Scala used to work that way, but it turned out not to be a workable solution. Gory details at https://issues.scala-lang.org/browse/SI-4214. (Perhaps someone knows of a more concise writeup of the considerations that forced that decision, e.g. an SO answer?)

2 Likes