2.4 Combining Multiple Operators
Pyret has only one rule for using multiple operators in a single expression: different operators must be explicitly grouped by parentheses, and evaluation always proceeds from left to right.
Therefore, the following expressions are not allowed:
1 + 1 - 1 1 + 1 > 1 1 + 1 == 2 (3 * 4 / 2) (3 * 4) / 1 + 1 3 * (4 / 2) + 1
And will raise an error like:
Pyret disallows mixing operators without clearly defining the operator precedence using parentheses. Conversely, any number of identical operators can be grouped without pairwise parentheses. These expressions are all valid in Pyret:
1 + (1 - 1) (1 + 1) > 1 1 + 1 + 1 1 - 1 - 1 (1 + 1) == 2 3 * (4 / 2) (3 * (4 / 2)) (3 * 4) / (1 + 1) (3 * (4 / 2)) + 1
2.4.1 But why not use precedence?
Note for non-American readers: if you’ve never heard of dear Aunt Sally, it’s a mnemonic often used to memorize a standard order-of-operations.
Implicit operator precedence is a common source of errors among even experienced developers, so getting in the habit of explicitly defining precedence using parentheses is a good idea even when using languages that support implicit precedence.
Pyret has many operators, besides just the arithmetic ones: comparison and logical operators, equality operators, testing operators, and others. While it’s possible to memorize the precedence among just a few of these operations, it’s both tedious and unenlightening to memorize precedences among every possible combination of operators. Instead, parentheses make the programmer’s intent explicit.
check: (~100000000000000 + ~-100000000000000) + ~0.0001 is-roughly ~0.0001 ~100000000000000 + (~-100000000000000 + ~0.0001) is-roughly ~0 end
A similarly nuanced problem occurs with comparison operators: writing 1 < 2 < 3 is legal, but will produce an error at runtime, because true cannot be compared to 3. Likewise, 1 == 1 == 1 will produce false, because 1 == 1 evaluates to true, which is not equal to 1. Some other languages attempt to make these expressions “work” and evaluate to true, but by doing so they’ve effectively created new operators that take in three arguments, since their behavior cannot be expressed in terms of any pairwise usage of a binary operator.
Pyret takes the firm stance that since every operator has its own quirks, it does not make sense to create a complex, hard-to-predict set of rules for how different operators interact. Instead, it uses just one single rule, with the easy use of parentheses to resolve any unintended behaviors.