SIP-NN: Make infix type alias precedence like expression operator precedence

I’m a contributor to the singleton-ops library, and we have reached the point where the following is possible:

import singleton.ops._

val four1 : 4 = implicitly[2 + 2]
val four2 : 2 + 2 = 4
val four3 : 1 + 3 = implicitly[2 + 2]

And also:

import singleton.ops._

class MyVec[L] {
  def doubleSize = new MyVec[2 * L]
  def nSize[N] = new MyVec[N * L]
object MyVec {
  implicit def apply[L](implicit check : Require[L > 0]) : MyVec[L] = new MyVec[L]()
val myVec : MyVec[10] = MyVec[4 + 1].doubleSize
val myBadVec = MyVec[-1] //fails compilation, as required

You can easily see that the code above makes type operations very intuitive.
Unfortunately, the ‘trouble’ begins with lack of precedence of infix types. E.g.

val works : 1 + (2 * 3) + 4 = 11
val fails : 1 + 2 * 3 + 4 = 11 //left associative:(((1+2)*3)+4))) = 13

I want to create a SIP for this, and modify the specification so that infix type precedence and associativity are more like expression infix operator precedence and associativity.

The specification for infix types precedence and associativity is as follows:

The specification for expression infix operator precedence and associativity is as follows:

Please respond. I value your input.


I ran into this myself. See:

Btw, while invistagating this, I ran into the fact that right-associative type aliasing works as (un)expected:

type ~>[A,B] = Map[A,B]
type ~~~>[A,B] = Pair[A,B]
classOf[A ~> (B ~~~> C)] // Map[A,Pair[B,C]]


type ~:[A,B] = Map[A,B]
type ~~~:[A,B] = Pair[A,B]
classOf[A ~: B ~~~: C] // Map[A,Pair[B,C]]

There is also this suggestion to allow precedence and associative control to the user . I personally don’t like it, as it can generate more confusion than be helpful.

@jvican How long to wait before introducing a PR with the new SIP?

Hello @soronpo,

Thanks for submitting this proposal! Please, feel free to submit a PR to this repository with the details of your proposal. These details would include a motivation section, a current description of the state-of-the-art on type alias precedence (and weird issues like the one @pathikrit mentions), and a description of your proposed solutions and the required changes to the spec.

For an exemplary proposal you can get inspiration from, see this one or have a look at this comment where @dwijnand gives you some advice on how to write a proposal (aside from this template that we provide). For full information on the steps to get a proposal through, check the official instructions here (note that I have to modify the section describing where to start discussing a proposal since the mentioned mailing lists are now retired). If you hurry up, we may review it the 14th February, when we have our next meeting! Otherwise, we’ll do it next month, so don’t stress ;).

For my fellow archeologists on the Internet, see this related thread in the now retired scala-sips mailing list in which @soronpo originally proposed this feature to the Scala language.

Thank you so much for this proposal. On a personal basis, I think that having type alias precedence behave exactly as operator precedence makes sense and helps Scala developers reason about the language more easily. I think that it is predictable and, therefore, what anyone would expect.


I wish to emphasize that what I originally published on scala-sips regards to the lack of bracket-less prefix semantics in comparison with expression prefix operations. I will fold this issue with this SIP as well, but will split them in the proposal to allow the committee to approve one, but not the other.

Thank you @jvican


Added the SIP :slight_smile:


Infix extractors also don’t follow symbolic precedence. Credit to @propensive.

Any particular reason why this hasn’t been updated in any way for the past two years? I really wish Scala 2.13 had come out with a singleton ops library.


For what it’s worth, it’s implemented in Dotty/Scala-3.

1 Like