Search code examples
scalaoperator-overloadingoperator-precedence

Why has !== lower precedence than === in Scala?


Following code does not compile:

implicit class TripleEq(val x: Int) {
  def === (y: Int) = x == y
  def !== (y: Int) = x != y
}

val a = 0
val b = 1

if (a == a && b === b) {
  println("Equal")
}

if (a != b && a !== b) {
  println("Not equal")
}

The error is:

type mismatch; found : Int required: Boolean

The error goes away when I enclose the a !== b in parentheses.

I thought that operator precedence is defined by its first letter (see Tour of Scala) and therefore the precedence of !== should be the same as of ===, != or ==.

Why are parentheses required in the code above?


Solution

  • The answer is in the language specification of Assignment Operators:

    There's one exception to this rule, which concerns assignment operators. The precedence of an assignment operator is the same as the one of simple assignment (=). That is, it is lower than the precedence of any other operator.

    6.12.14 Assignment Operators

    An assignment operator is an operator symbol (syntax category op in Identifiers) that ends in an equals character “=”, with the exception of operators for which one of the following conditions holds:

    • the operator also starts with an equals character, or
    • the operator is one of (<=), (>=), (!=).

    Based on these rules !== is considered to be an assignment operator, while === is not.