Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are logical operators in JavaScript left associative?

Tags:

The logical AND and OR operators are the only lazy operators in JavaScript along with the ternary conditional operator. They are tested for short-circuit evaluation using the following rules:

false && anything === false true || anything === true 

This is the same way it is implemented in Haskell:

(&&) :: Bool -> Bool -> Bool False && _ = False True  && x = x  (||) :: Bool -> Bool -> Bool True  || _ = True False || x = x 

However according to MDN logical operators in JavaScript are left associative. This is counter intuitive. In my humble opinion they should be right associative. Haskell does the right thing. Logical operators in Haskell are right associative:

infixr 3 && infixr 2 || 

Consider the following expression in Haskell:

False && True && True && True 

Because && is right associative in Haskell the above expression is equivalent to:

False && (True && (True && True)) 

Hence it doesn't matter what the expression (True && (True && True)) evaluates to. Because of the first False the entire expression is reduced to False in a single step.

Now consider what would happen if && was left associative. The expression would be equivalent to:

((False && True) && True) && True 

It would now take 3 reductions to evaluate the entire expression:

((False && True) && True) && True (False && True) && True False && True False 

As you can see it makes more sense for logical operators to be right associative. This brings me to my actual question:

Why are logical operators in JavaScript left associative? What does the ECMAScript specification have to say about this? Are logical operators in JavaScript actually right associative? Does the MDN docs have incorrect information about the associativity of logical operators?


Edit: According to the specification logical operators are left associative:

LogicalANDExpression = BitwiseORExpression                      | LogicalANDExpression && BitwiseORExpression  LogicalORExpression = LogicalANDExpression                     | LogicalORExpression || LogicalANDExpression 
like image 254
Aadit M Shah Avatar asked Dec 15 '13 06:12

Aadit M Shah


People also ask

Are logical operators left-associative?

The grammar in the specification defines the logical operators as left associative.

Are logical operators associative?

The answer of this question is Associativity, and logical operators, which have the same Precedence in a single expression or say when two or more operators (such as (&&) and (&&)) with the same precedence can be applied to the same operand, the left to right associativity will cause the left-most operator to be ...

Why associativity of * is from left to right?

Associativity is the left-to-right or right-to-left order for grouping operands to operators that have the same precedence. An operator's precedence is meaningful only if other operators with higher or lower precedence are present. Expressions with higher-precedence operators are evaluated first.

Why is 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.


1 Answers

For any decent compiler the chosen associativity of these operators are pretty much irrelevant, and the outputted code will be the same regardless. Yes, the parse tree is different, but the emitted code doesn't need to be.

In all of the languages of the C family that I know of (to which Javascript also belongs), the logical operators are left associative. So the real question becomes, why do C-like languages define logical operators as left-associative? Since the chosen associativity is irrelevant (in terms of semantic, and in terms of efficiency), my suspicion is that the most "natural" (as in "what the majority of the other operators use") associativity was chosen, although I don't have any sources to back up my claims. Other possible explanation is that left associative operators take less stack space to parse using an LALR parser (which is not a big concern nowadays, but probably was back when C appeared).

like image 51
Pedro Rodrigues Avatar answered Nov 02 '22 22:11

Pedro Rodrigues