I’m trying to make a DSL for defining algebraic equations. Given that this is the order of infix operation precedence in scala:
(all letters)
|
^
&
= !
< >
:
+ -
* / %
(all other special characters)
This doesn’t work well for algebraic equations as:
^ is defined with lower precedence than + and *. So using it for exponentiation results in a lot of parenthesis.
If I wanted to use ** for exponentiation, it seems to have equal precedence to *. Again resulting in a lot of parenthesis.
I also tried /\ but this seems like it also has the same precedence as *.
This kind of destroys the elegance of having a DSL, if you have to parenthesize everything.
So is there anything I can do to get around this infix operator precedence?
If nothing can be done in current scala; I did have one idea for a future version. Perhaps making it so an operator of the same symbol repeated would have higher precedence than one of the same symbol repeated fewer times.
So ** would have higher precedence than *, for example.
Looks like an extremely dirty hack around synonymity in real life (like a tradition of denoting both power and bitwise xor with ^) and fact that operators naming rules in the language declare that synonymity is unwanted for operators.
You could use quasiquotes. So you write dsl" $a * $b ** $c " and inside the quote you can define your own parsing rules and precedences. If the types of things inserted into the quote are homogenous and the quote always returns the same type, you don’t even need a macro.