Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does left-to-right associativity mean?

Tags:

c++

glm-math

I am confused about the definition of left-to-right and right-to-left associativity. I have also seen them called left associativity and right associativity and would like to know which corresponds to which.

I know that it relates to the order that operations with the same precedence are preformed, as in whether a = x * y * z means a = x * (y * z) or a = (x * y) * z. I don't know which one is left-to-right associative and which is right-to-left associative.

I have tried Googleing it but all I have been able to find is tables of what the associativity of different operators are in c++. Looking at all the examples has just made me more confused.

What also confuses me further is that:

glm::vec4 transformedVector = translationMatrix * rotationMatrix * scaleMatrix * originalVector; 

preforms the scaling matrix multiplication first, followed by the rotation matrix followed by the translation. In this example the matrices are all of type glm::mat4 and the vectors are of type glm::vec4. Is this left-to-right or right-to-left associativity? Is this the same as normal multiplication or is multiplication of glm types different?

like image 240
Francis Avatar asked Aug 31 '14 05:08

Francis


People also ask

What is meant by left-associative?

Left-associative operators of the same precedence are evaluated in order from left to right. For example, addition and subtraction have the same precedence and they are left-associative. In the expression 10-4+2, the subtraction is done first because it is to the left of the addition, producing a value of 8.

What does the term associativity determine?

In programming languages, the associativity (or fixity) of an operator is a property that determines how operators of the same precedence are grouped in the absence of parentheses; i.e. in what order each operator is evaluated.

Which operators has its associativity from right to left?

Which of the following operators has its associativity from right to left? Explanation: All of the operators shown above have associativity from left to right, except exponentiation operator (**) which has its associativity from right to left.


2 Answers

You normally read left to right. You normally do math left to right. This is left to right associativity and it is most common.

Most people will solve

x = 23 + 34 + 45 

by grouping it

x = (23 + 34) + 45 

this is left-to-right associativity. You can remember it because you read and do math left to right.

For addition in mathematics it does't matter too much. You always get the same result either way. This is because addition is associative. To say an operation is associative means left to right and right to left association are the same thing. For addition in programming it still matters because of overflows and floating point arithmetic (but won't for normal-sized integers in any reasonable language), so when you have a 2 AM bug with large numbers and flippant use of a+b and b+a, remember what order the addition happened in.

In your example:

glm::vec4 transformedVector = translationMatrix * rotationMatrix * scaleMatrix * originalVector 

You conceptually chomp through from the right-side first, since that is where the thing you are acting on is. However in C++, * is normally left-to-right associative and it is not possible to override this. glm may handle this in a number of ways: it may build up a cache of things to multiply waiting for the final vector to arrive then do right to left multiplication. It may also (more likely) use the theorem of algebra that matrix multiplication is fully associative, and just multiply out left-to-right, then assure the reader in the documentation that it's the same as thinking of it as right to left. However, you need to understand the implementation because as previously discussed it matters which way the implementation chooses to multiplying floating point numbers together.

For completeness, consider subtraction. What is a - b - c? Here it really does matter whether it is left or right associative. Of course in math we define it to b (a - b) - c, but some strange programming language might prefer subtraction to be right associative, and take a - b - c to always mean a - (b - c). This alien language had better have a documentation page specifying that - is right-associative, because it is part of the operation specification, not something you can tell simply from looking at the operator's use.

like image 200
djechlin Avatar answered Sep 20 '22 18:09

djechlin


You can see that from the following words:

When we combine operators to form expressions, the order in which the operators are to be applied may not be obvious. For example, a + b + c can be interpreted as ((a + b) + c) or as (a + (b + c)). We say that + is left-associative if operands are grouped left to right as in ((a + b) + c). We say it is right-associative if it groups operands in the opposite direction, as in (a + (b + c)).

A.V. Aho & J.D. Ullman 1977, p. 47

like image 24
Daniel Avatar answered Sep 23 '22 18:09

Daniel