I was under the impression that specialization composes, but in the following example that doesn't seem to be the case:
trait Key [@specialized(Int) A] {
def up(k: A): Unit
}
class Test[@specialized(Int) A](key: Key[A], value: A) {
key.up(value)
}
If I dump this in the Scala REPL with :javap -v Test
, it seems that the call to key.up
still boxes the primitive:
public Test(Key, java.lang.Object);
Code:
Stack=2, Locals=3, Args_size=3
0: aload_0
1: aload_1
2: putfield #17; //Field key:LKey;
5: aload_0
6: aload_2
7: putfield #19; //Field value:Ljava/lang/Object;
10: aload_0
11: invokespecial #24; //Method java/lang/Object."<init>":()V
14: aload_0
15: getfield #17; //Field key:LKey;
18: aload_0
19: getfield #19; //Field value:Ljava/lang/Object;
22: invokeinterface #30, 2; //InterfaceMethod Key.up:(Ljava/lang/Object;)V
27: return
So is specialization completely useless for developing generic implementations? In my case, data structures, it would completely undermine the effort to develop concise modular code. So I hope I am missing something...
You are looking at the unspecialized version of the class.
When I try I see another class Test$mcI$sp
that is the specialized compiled version. This is kind of the point, it must create a separate class that is specialized for the primitive you specify.
Edit: if looking for the specialized class in the REPL you need to get the full class name. By default, the REPL trims the actual context where the class is stored, so you need to get it by println eg:
scala> println(new Test(1).getClass.getName)
$line1.$read$$iw$$iw$Test$mcI$sp
scala> :javap $line1.$read$$iw$$iw$Test$mcI$sp
…
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With