worldterminator
worldterminator

Reputation: 3076

how to modify self-defined scala operators' precedence

Is it possible to modify the precedence of any self-defined operators? For example, I implement elementary arithmetic with totally self-defined operators.

  case class Memory(name:String){
    var num:Num = null

    def <<=(x:Num): Unit = {
      println(s"assign ${x.value}")
      this.num = x
    }
  }

  case class Num(var value:Int) {
    def +|+(x:Num) = {
      println("%d + %d = %d".format( value,x.value,x.value + value ))
      Num(value + x.value)
    }
    def *|*(x:Num) = {
      println("%d * %d = %d".format( value,x.value,x.value * value ))

      Num(value * x.value)
    }
  }


  val m1 = Memory("R")

  val a = Num(1)
  val b = Num(3)
  val c = Num(9)
  val d = Num(12)

  m1 <<= a *|* b +|+ c +|+ d *|* a

  println("final m1 ",m1.num.value)

The results are

1 * 3 = 3
3 + 9 = 12
12 * 1 = 12
12 + 12 = 24
assign 24
(final m1 ,24)

Apparently the precedence is correct. I want *|* be the same precedence as * and +|+ the same as +, <<= is equivalent as = as well. How scala figure it out?

Upvotes: 2

Views: 696

Answers (1)

TheMP
TheMP

Reputation: 8427

Answering the question about modyfing operator precedence - to change it you basically just have to change the first character of your custom operator - this is how scala figures out precedense for infix operators, by just looking at the first character. So if you eg. add an operator *|+:

  1. It will have same precedence as *|*, like with * and *.
  2. "Bigger" precedence than +|+, just like with * and +.

Unfortunately there is no other way to deal with it right now. No custom annotations/weights and so on to avoid making reading code too fuzzy.

The precedence rules are very well summarized here - Operator precedence in Scala.

About your issue though - you get the right results.

*|*, as well as * are left-associative operators and their first character is *, so they have equal precedense.

Your operation:

a *|* b +|+ c +|+ d *|* a

Translates to

a * b + c + d * a, which is 1 * 3 + 9 + 12 * 1.

Applying standard precedence rules - (a*b) + c + (d*a) result is 24.

Upvotes: 1

Related Questions