javascriptoperator-precedenceexponentiationecmascript-2016

# JavaScript exponentiation unary operator design decision

So I was fooling around with the new exponentiation operator and I discovered you cannot put a unary operator immediately before the base number.

``````let result = -2 ** 2; // syntax error
let result = -(2 ** 2); // -4
let x = 3;
let result = --x ** 2; // 4
``````

From the documentation on MDN:

In JavaScript, it is impossible to write an ambiguous exponentiation expression, i.e. you cannot put a unary operator (`+`/`-`/`~`/`!`/`delete`/`void`/`typeof`) immediately before the base number.

In most languages like PHP and Python and others that have an exponentiation operator (typically `^` or `**`), the exponentiation operator is defined to have a higher precedence than unary operators such as unary `+` and unary `-`, but there are a few exceptions. For example, in Bash the `**` operator is defined to have a lower precedence than unary operators.

I understand this was made an error by design. I don't understand this design decision. Who's really going to be surprised that `-x ** 2` is negative? This follows not only other mainstream programming languages but a mathematical notation that has been in common use for hundreds of years and is taught to every high school algebra student.

In Javascript `'1'+ 2` is `'12'` and `'1'-2` is `-1` but `-1**2` raises an error because it could be ambiguous? Help me understand this design decision.

Solution

• I don't understand this design decision.

Who's really going to be surprised that `-x ** 2` is negative?

Enough people to matter. Some relevant quotes from the above resources:

• "making `**` bind tighter than unary operators would break `x**-2`. And making it sometimes tighter and sometimes looser would be too confusing and lead to other opportunities for precedence inversion." - Waldemar Horwat
• "Given the conflict between the history of `**` in other languages, [and] the general pattern that unary binds tighter than binary, any solution at this point will confuse many people." - Mark S. Miller
• "acknowledge the prospect of significant whitespace: `-x**2 === -(x ** 2)` and `-x ** 2 === (-x) ** 2`" - Alexander Jones
• "The problem is, however rare unary minus before an exponentiation expression may be, the lack of superscript-with-smaller-font sugests that `-` binds tighter than `**`. And indeed apart from dot (a special form whose right operand must be a lexical identifier-name) and square brackets (which isn't an infix operator per se), unary operators bind tighter than binary in JS as in C and other C-derived languages." - Brendan Eich
• "For math it seems obvious that `-52`. But for `-5 ** 2`, because of the whitespace around the infix operator. Even without space, `-` seems to be part of the literal." - Dave Herman
• [Regarding programming language precedence], "effectively zero people have an intutition about this from other languages. Agree people have an itutition that `**` is the exponentiation operator. But people usually try to avoid dark corners so they never develop an intuition for negative bases." - Dave Herman

In Javascript `'1'+ 2` is `'12'` and `'1'-2` is `-1` but `-1**2` raises an error because it could be ambiguous?

Well they put considerably more effort in the design of extensions to the language today :-) It's the best solution that they could reach consensus for.