Operator precedence and associativity

When we write something like \(1 + 2 \times 3\), how do we know what it means? Does it mean \((1 + 2) \times 3\), or \(1 + (2 \times 3)\)? Of course, you are familiar with the usual “order of operations”, where multiplication comes before addition, so in fact \(1 + 2 \times 3\) should be interpreted as \(1 + (2 \times 3) = 1 + 6 = 7\).

Another way to say this is that multiplication has higher precedence than addition. If we think of operators as “magnets” that attract operands, higher precedence operators are like “stronger magnets”.

Another issue arises when operators are repeated, or when operators with the same precedence are used together. For example, does \(4 - 3 - 2 - 1\) mean \(((4 - 3) - 2) - 1\) or \(4 - (3 - (2 - 1))\)? In fact, it means the former, because addition and subtraction are done “left to right”; we say they are left associative. On the other hand, exponentiation is right associative, meaning that 1 ^ 2 ^ 3 ^ 4 = 1 ^ (2 ^ (3 ^ 4)).

Every operator in Disco has a precedence level and associtivity, and Disco uses these to determine where to put parentheses in expressions like 1 + 2 * 3 or 5 > 2 ^ 2 + 1 and 7 > 2 ==> true. You might have memorized something like PEMDAS, but Disco has so many operators that memorizing their precedence levels is out of the question! Instead, we can use the :doc command to show us the precedence level and associativity of different operators.

Disco> :doc ^
~^~ : ℕ × ℕ → ℕ
precedence level 13, right associative

Disco> :doc +
~+~ : ℕ × ℕ → ℕ
precedence level 7, left associative

Disco> :doc >
~>~ : ℕ × ℕ → Bool
precedence level 5, right associative

Disco> :doc and
~and~ : Bool × Bool → Bool
precedence level 4, right associative

Disco> :doc ==>
~==>~ : Bool × Bool → Bool
precedence level 2, right associative