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?
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.