3

In Scala, the + operator is actually a method called + implemented by objects. In the case of Int, from Int.scala:

/** Returns the sum of this value and `x`. */ def +(x: Int): Int 

And 1-arity methods with no side-effects can be called using an infix notation:

// this caller method callee // and this caller.method(callee) // are identical, so 1 + 2 // is actually (1).+(2) 

But I can't find on Int.scala how the language actually performs the integer addition inside the + method.

How is it done?

1 Answer 1

12

Compiler magic. The compiler translates into the intrinsic "iadd" instruction on the JVM.

class Test { def first(x: Int, y: Int) = x + y def second(x: Int, y: Int) = (x).+(y) } 

Which compiles down to exactly what you'd hope for in either case

$ javap -c Test.class Compiled from "Test.scala" public class Test { public int first(int, int); Code: 0: iload_1 1: iload_2 2: iadd 3: ireturn public int second(int, int); Code: 0: iload_1 1: iload_2 2: iadd 3: ireturn public Test(); Code: 0: aload_0 1: invokespecial #20 // Method java/lang/Object."<init>":()V 4: return } 

Similar things happen with other JVM primitive operations

If you implement "+" on your own class, it's just dispatched into a normal method call

class Test2 { def +(t2: Test2) = "whatever" def test = this + this } 

Becomes

$ javap -c Test2.class Compiled from "Test2.scala" public class Test2 { public java.lang.String $plus(Test2); Code: 0: ldc #12 // String whatever 2: areturn public java.lang.String test(); Code: 0: aload_0 1: aload_0 2: invokevirtual #19 // Method $plus:(LTest2;)Ljava/lang/String; 5: areturn public Test2(); Code: 0: aload_0 1: invokespecial #23 // Method java/lang/Object."<init>":()V 4: return } 

Notice the method is named "$plus." That's because "+" isn't a valid method name as far as the JVM is concerned. Other symbols that aren't valid JVM names have similar translations.

In all these cases, scalac uses the static type to determine wether to emit a method call or a JVM primitive.

The actual determination is made in https://github.com/scala/scala/blob/2.11.x/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala , a phase that happens very late in the compiler's chain. For the most part all previous phases treat x + y as if it's going to be a method call regardless of x's type.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.