When I manually converted Scala 2 code to Scala 3, operator precedence for my DSL changed, and it took me a long time to debug and fix. It seems the handling of :
is different:
extension (i1: Int) def ~>:(i2: Int) = i1 < i2
extension (i1: Int) def ~>(i2: Int) = i1 < i2
class Wrap(val i: Int):
def ~>:(w: Wrap) = i ~>: w.i
def ~>(w: Wrap) = i ~> w.i
// `Wrap` preserves `~>`
println(1 ~> 2) // true
println(Wrap(1) ~> Wrap(2)) // true
// `Wrap` does not preserve `~>:`
println(1 ~>: 2) // true
println(Wrap(1) ~>: Wrap(2)) // false
My mental model was:
- For methods ending in
:
, the reciever is the thing on the right - extension methods are just methods: it's as if the method is added to the class
My mental model seems to be wrong. What's the right way of explaining what's happening?
Links would help, I checked the Scala 3 docs and didn't find anything about how custom operators associate.
Update
I tried adding infix
keyword before def
, but it doesn't change what is printed in this example.