Precedence and Associativity

Let's discuss the precedence and associativity of arithmetic operators in this lesson.

Precedence

Operator precedence determines which operation is performed first in an expression with more than one operator. Operator precedence in Perl is similar to that of regular arithmetic operators.

  • *, /, % operators have equal precedence.
  • + , - operators have equal precedence.
  • *, / , % have a higher precedence than + , -.

The operator with higher precedence is executed first in an expression.

The part of the expression in the parentheses () is evaluated before the ones outside the parentheses.

Associativity

Associativity is used when two operators of the same precedence appear in an expression.

Left associativity

Left associativity occurs when an expression is evaluated from left to right. For example * and / have the same precedence and their associativity is left to right, so the expression

100 / 10 * 10 

is treated as:

(100 / 10) * 10

Right associativity

Right associativity occurs when an expression is evaluated from right to left. Like most programming languages, = and print in Perl have right associativity. Similarly, combined assignment operators (+=, -=, *=, \=) have the right associativity.

Run the following code to see a few examples:

Press + to interact
print "5 - 3 + 2 = ". (5-3+2); # 5-3+2 is treated as (5-3)+2
print "\n";
print "5 - (3 + 2) = ". (5-(3+2)); # 5-3+2 is treated as 5-(3+2) => 0
print "\n";
print "5 + 3 * 2 = ". (5+3*2); # 5+3*2 is treated as 5+(3*2)
print "\n";
print "15 / 3 * 5 = ". (15/3*5); # 15/3*5 is treated as (15/3)*5
print "\n";
print "42 + 7 % 2 = ". (42+7%2); # 42+7%2 is treated as 42+(7%2)
print "\n";
print "(42 + 7) % 2 = ". ((42+7)%2); # 42+7%2 is treated as (42+7)%2 => 1
print "\n";
$a = 6;
print "6 += 4 => ". ($a += 4); # compined addition operators have right associativity.

Operators with the same precedence and associativity

Naturally, you must be thinking, what will happen if there are two operators with the same precedence and associativity in an expression.

In this case, the expression is evaluated from left to right, i.e., it evaluates the operator that comes first (on the left).

For instance, % and * have the same precedence and associativity. Thus, given an expression $a = 5 * 3 % 2; the value of $a will be 1 because

(53)%2=15%2=1(5 * 3) \% 2 = 15\%2=1

And given an expression $a = 5 % 3 * 2; the value of $a will become 4 because

(5%3)2=(22)=4(5 \% 3) * 2 = (2 * 2) = 4

Run the code snippet below to see how this works:

Press + to interact
$a = 5 * 3 % 2; # $a now is (5 * 3) % 2 => (15 % 2) => 1
print $a."\n";
$a = 5 % 3 * 2; # $a now is (5 % 3) * 2 => (2 * 2) => 4
print $a."\n";

Conclusion

Thus, precedence and associativity are two characteristics of operators that determine the evaluation order of subexpressions in absence of brackets. This is illustrated in the figure below:

Let’s run the following code to check the output:

Press + to interact
print (34 + 12 / 4 - 45);

Remember: It is good to know precedence and associativity rules, but the best thing is to use parenthesis. Parenthesis increases the readability of the code as the reader doesn’t have to see the table to find out the order.