I am currently getting into Scala and am wondering about the difference it makes to use object notation when calling methods ending with ':'. As a method name ending in ':' would normally produce right-side associativity, this seems to change when invocating such a method with object notation.

Example:

scala> 3 +: List(1,2) 
res1: List[Int] = List(3, 1, 2) 

scala> List(1,2) +: 3 // does not compile due to right side associativity

scala> (List(1,2)).+:(3) 
res2: List[Int] = List( 3, 1, 2)

Now I do not understand why the right-associativity feature gets disabled by using object notation. Could someone explain this or link to the documentation on this issue?

1

There are 1 best solutions below

1
On BEST ANSWER

From the spec, "Infix Operations":

The associativity of an operator is determined by the operator's last character. Operators ending in a colon `:' are right-associative. All other operators are left-associative.

Method +: is defined on the List, which is why (List(1,2)).+:(3) works. Its implementation is such that the element is put in the front, so equivalent to 3 :: List(1, 2), but that's irrelevant here.

Using infix notation List(1,2) +: 3 won't work, because (as stated in the spec) all infix operators ending with a colon are right-associative, which means that the "right hand side" is using the operator with "left hand side" as a parameter, instead of vice-versa.

Basically,

1 +: 2 +: 3 +: List(4, 5) 

and

List(4, 5).+:(3).+:(2).+:(1)

have identical effect (I know that has been pretty much obvious in your question already, but I'm just emphasizing the right-associativity).

So, to answer your question in one simple sentence: it's not that right-side associativity is removed in object notation, it's more that it's added in the infix notation, but only for methods ending with a colon.