History
Date | Version |
---|---|
Mar 10th 2019 | Pre-SIP |
Introduction/Motivation/Abstract
This SIP proposes to change the Scala language specification’s assignment operator language definition1, by modifying the 2nd exception from the operator is one of (<=), (>=), (!=)
to the operator begins with one of (<=), (>=), (!=)
.
The aim is to support additional comparison operators that also begin with <=
, >=
, and !=
, and also end in =
.
Motivating Example
This was encountered when creating a TypeSafeEquals2 implementation with the desired ===
and !==
operators. When used, it generates a compile exception if the types don’t match, avoiding an unintended comparison of unrelated types that would always fail. However, the existing language specification will generate a compile error when using !==
:
scala> 1 !== -1 || true
<console>:15: error: value || is not a member of Int
1 !== -1 || true
^
Since !==
ends in =
, its’ precedence is the same as an assignment operator, so 1 !== -1 || true
gets evaluated as 1 !== (-1 || true)
by the Scala compiler.
By modifying the exceptions definition to “begins with”, this should get compiled with the desired precedence of (1 !== -1) || true
.
Counter-Example
This can be worked around by using other operators:
scala> 1 =!= -1 || true
res0: Boolean = true
Implementation
def isOpAssignmentName: Boolean = name match {
case raw.NE | raw.LE | raw.GE | EMPTY =>
false
case name: SimpleName =>
name.length > 0 && name.last == '=' && isOperatorPart(name.head) &&
(name.length < 3 || !(name.startsWith(raw.NE) || name.startsWith(raw.GE) || name.startsWith(raw.LE))
case _ =>
false
}
Drawbacks
This is a piece of the language specification that may have never been changed and has unintended consequences which are unknown.
The scope of the change would affect any custom assignment operators that use the patterns:
!=[.*]=
>=[.*]=
<=[.*]=
If there are DSLs or other implemented assignment operators using the above patterns, then the scala code would not compile without modifying the first =
character to another.
Alternatives
As described in the counter-example, there are other operators available, and is not core functionality that is currently “broken” or has no alternative.