I was posed a question recently as to why the C++ expression
true == true == true compiled successfully. The person asking was sure that equality comparison held no associativity and that the expression was thus too ambiguous to be well-formed.
Well, in Ruby, this is the case:
Subtraction is left associative;
a - b - 3acts like
(a - b) - 3.
Assignment is right associative;
a = b = 3acts like
a = (b = 3).
Equality is not associative;
a == b == 3raises
In fact, C++'s equality operator is left associative, and my immediate thought was that Ruby's behaviour was a little odd.
However, on further thought, I realised that it makes quite a bit of sense.
For example, it essentially prevents the following mistake:
int x = 0, y = 0, z = 0; std::cout << (x == y == z); // false
Naively, especially when coming directly from a mathematics background, one might expect the output of this program to be
true because all three operands are equal.
But in fact, C++'s comparison takes only two operands, and when implicit associativity is applied explicitly with parentheses, the program's true behaviour becomes more obvious:
int x = 0, y = 0, z = 0; std::cout << ((x == y) == z); // true == 0 // false
Ruby's position of completely disallowing such a form in its arithmetic expressions will prevent any such "bugs". Perhaps it would have been better had C++ adopted this position as well.