2 ms·
Personally, I don't have a problem with deep magic that I don't completely understand operating in my code, as long as its semantics are clear and obvious. If
by moomin 15y ago
Personally, I don't have a problem with deep magic that I don't completely understand operating in my code, as long as its semantics are clear and obvious. If I didn't, I doubt I'd code in C, never mind Scala.
I'm more interested in what this compiles to in the JVM, and what its performance overhead is.
- fhars 15y agoThe size method from the post compiles to exactly the same bytecode as the unsafe def sizeAny(t: Any) = t match { case i : Int => i case s : String => s.length } The only difference is that the method has an additional unused parameter for the <:< witness [edit: which must be provided at the call site, so there is some overhead (a method call and an object allocation) there] and that the compiler guarantees that it will never throw a MatchError exception. As proof the disassembly: public int size(java.lang.Object, scala.Predef$$less$colon$less); Code: 0: aload_1 1: astore_3 2: aload_3 3: instanceof #8; //class java/lang/Integer 6: ifeq 16 9: aload_3 10: invokestatic #14; //Method scala/runtime/BoxesRunTime.unboxToInt:(Ljava/lang/Object;)I 13: goto 30 16: aload_3 17: instanceof #16; //class java/lang/String 20: ifeq 31 23: aload_3 24: checkcast #16; //class java/lang/String 27: invokevirtual #20; //Method java/lang/String.length:()I 30: ireturn 31: new #22; //class scala/MatchError 34: dup 35: aload_3 36: invokespecial #26; //Method scala/MatchError."<init>":(Ljava/lang/Object;)V 39: athrow public int sizeAny(java.lang.Object); Code: 0: aload_1 1: astore_2 2: aload_2 3: instanceof #8; //class java/lang/Integer 6: ifeq 16 9: aload_2 10: invokestatic #14; //Method scala/runtime/BoxesRunTime.unboxToInt:(Ljava/lang/Object;)I 13: goto 30 16: aload_2 17: instanceof #16; //class java/lang/String 20: ifeq 31 23: aload_2 24: checkcast #16; //class java/lang/String 27: invokevirtual #20; //Method java/lang/String.length:()I 30: ireturn 31: new #22; //class scala/MatchError 34: dup 35: aload_2 36: invokespecial #26; //Method scala/MatchError."<init>":(Ljava/lang/Object;)V 39: athrow