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 mon 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.
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 mon 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.
-
2
Writing
-x ** 2
instead of- x**2
would make it ambiguous alone. – Bergi Commented Nov 2, 2017 at 6:41 - Well, I believe I was always taught at school that -x raised to the power of y produces a positive number. So, -1**2 should produce 1. At least this is what I believe was taught, and I am sufficiently confident that my belief is correct. – doubleOrt Commented Dec 9, 2017 at 16:55
- 1 Why the heck was this question downvoted ? – doubleOrt Commented Dec 9, 2017 at 17:25
-
1
@doubleOrt - Agreed, very strange (about the vote). BTW, in math,
-1²
is-1
. It's-(1²)
, not(-1)²
. I went 'round and 'round in my head on that one and finally punted and asked the question. It's been that long since math class. But I'm also a bit embarrassed to have asked, since I routinely see things like-2³² + 1
and have no trouble interpreting that correctly (2³² = 4294967296, -4294967296 + 1 is -4294967295). – T.J. Crowder Commented Dec 5, 2018 at 15:54 - @T.J._Crowder I am actually quite ashamed of my ment now that I read it, -1**2 only takes a basic understanding of operator precedence in Math, and "(-x)" raised to the power of "y" does not always produce a positive. – doubleOrt Commented Dec 6, 2018 at 13:43
2 Answers
Reset to default 12I don't understand this design decision.
Read more about it at https://esdiscuss/topic/exponentiation-operator-precedence, https://esdiscuss/topic/power-operator-why-does-2-3-throws, https://github./rwaldron/tc39-notes/blob/master/meetings/2015-09/sept-23.md#exponentiation-operator and https://github./rwaldron/tc39-notes/blob/master/meetings/2015-09/sept-24.md#exponentiation-operator.
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 breakx**-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.
Since we usually interpret -52 as -25
, I suggest we allow -5 ** 2
(which would be -25
), then we disallow 5**-2
just like we also disallow 5--2
, 5+* 2
, 5*/2
, etc where we do not put different operators one after another.
Allowing -5**2
would not break with the math munity and their libraries where they usually write like -5^2
and 5^(-2)
and 5-(-2)
instead of just 5--2
.