SIP-NN - Match infix & prefix types to meet expression rules
By: Oron Port
Feb 7th 2017
Feb 9th 2017
Updates from feedback
Feb 10th 2017
Updates from feedback
Your feedback is welcome! If you’re interested in discussing this proposal, head over to this Scala Contributors thread and let me know what you think.
Currently scala allows symbol operators (-, *, ~~>, etc.) for both type names and definition names.
Unfortunately, there is a ‘surprise’ element since the two differ in behaviour:
Infix operator precedence and associativity
Infix types are ‘mostly’ left-associative,
while the expression operation precedence is determined by the operator’s first character (e.g., / is precedent to +).
Please see Infix Types and Infix Operations sections of the Scala specifications for more details.
Prefix operators bracketless unary use
While expressions have prefix unary operators, there are none for types. See the Prefix Operations section of the Scala specification.
This is a lacking feature of the type language Scala offers. See also interactions of this feature with other Scala features, further down this text.
The proposal is split into two; type infix precedence, and prefix unary types. Note to the SIP committee: It might be better to vote on the two parts separately.
Proposal, Part 1: Infix type precedence & associativity
Make infix types conform to the same precedence and associativity traits as expression operations.
Proposal, Part 2: Prefix unary types
Add prefix types, exactly as specified for prefix expression.
The general motivation is developers expect terms and types to behave equally regarding operation precedence and availability of unary types.
Dotty infix type similarity
Dotty infix type associativity and precedence seem to act the same as expressions.
No documentation available to prove this, but the infix example above works perfectly in dotty.
We currently loose some of the intuitive appeal due to the precedence issue:
Developer issues example
This stackoverflow question demonstrate developers are ‘surprised’ by the difference in infix precedence, expecting infix type precedence to act the same as expression operations.
Interactions with other language features
Variance annotation uses the - and + symbols to annotate contravariant and covariant subtyping, respectively. Introducing unary prefix types may lead to some developer confusion.
Negative Literal Types
Negative literal types are annotated using the - symbol. This can lead to the following confusion:
The above example demonstrates a case of two types MinusFortyTwo and NegateFortyTwo which are different. They may be equivalent in view (implicit conversion between the two type instances), but they are not equal.
Note: It is not possible to annotate a positive literal type in Scala (checked both in TLS and Dotty):
This means that if unary prefix types are added, then +42 will be a type expansion of unary_+.
Changing infix type associativity and precedence affects code that uses type operations and conforms to the current specification.