Power operator, why does -2**3 throws?

# Cyril Auburtin (8 years ago)

I would expect -2**3 to return -8, or -2**2 == -4, since it should be like -(2**3)

Firefox gives a clearer error then Chrome with:

SyntaxError: unparenthesized unary expression can't appear on the

left-hand side of '**'

Is there a reason for this restriction? Python does it -2**3 fine

# J Decker (8 years ago)

probably because it's floating point native not integer like you'd think, so -2.00000001 ** 3 is hard?

# Cyril Auburtin (8 years ago)

What does it change if it handles floats?

I just checked developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence

unary + is 16, while exponentiation is 15, so the opposite order that I thought

2016-10-14 13:37 GMT+02:00 J Decker <d3ck0r at gmail.com>:

# Bergi (8 years ago)

Cyril Auburtin schrieb:

I would expect -2**3 to return -8, or -2**2 == -4, since it should be like -(2**3)

You would, others would not. -2 ** 2 clearly should return 4, shouldn't it?

Is there a reason for this restriction? Python does it -2**3 fine

Because of the ambiguity it has been decided to make it a syntax error if the two operators are used together. If you want -(2**3), you have to write it like that, and if you want (-2)**3 you have to write it explicitly as well. See esdiscuss.org/topic/exponentiation-operator-precedence for the full discussion.

# Cyril Auburtin (8 years ago)

Ah, ok, a bit sad because all more scientific languages, and python too, all math books, all will use -e^3 for meaning -(e^3) (^ or **), because it's just -exp(3) or -pow(E, 3)

and (-1)^n otherwise, when we want to take the signs with.

If you wanted to avoid any confusion you could have forbidden 2**2**3 too because it's not obvious it's right associative

But ok, thanks for the explanation.

2016-10-14 14:05 GMT+02:00 Bergi <a.d.bergi at web.de>:

# Cyril Auburtin (8 years ago)

I was testing something caub.github.io/misc/calculator, and I didn't see how it would be a problem to have the precedence of ** higher than unaries.

But at least I'm happy something like (2).pow(3) wasn't chosen.

Thanks anyway and sorry for discussing something already frozen in spec anyway

2016-10-14 14:33 GMT+02:00 Cyril Auburtin <cyril.auburtin at gmail.com>:

# Rick Waldron (8 years ago)

On Fri, Oct 14, 2016 at 7:31 AM Cyril Auburtin <cyril.auburtin at gmail.com>

wrote:

I would expect -2**3 to return -8, or -2**2 == -4, since it should be like -(2**3)

This was discussed extensively during the design process and determined that requiring user code to be explicit about its intention was the only sane design.

rwaldron/tc39-notes/blob/master/es7/2015-09/sept-23.md#exponentiation-operator

rwaldron/tc39-notes/blob/master/es7/2015-09/sept-24.md#exponentiation

# Rick Waldron (8 years ago)

Here's some more specific notes:

On Fri, Oct 14, 2016 at 7:31 AM Cyril Auburtin <cyril.auburtin at gmail.com>

wrote:

I would expect -2**3 to return -8, or -2**2 == -4, since it should be like -(2**3)

Math.pow(-2, 3) === -8 Math.pow(-2, 2) === 4

To get -4: -Math.pow(-2, 2)

Firefox gives a clearer error then Chrome with:

SyntaxError: unparenthesized unary expression can't appear on the left-hand side of '**'

That's correct.

Is there a reason for this restriction? Python does it -2**3 fine

Python is also inconsistent:

pow(-2, 2)

4

-2 ** 2 -4

Whereas, JavaScript is very consistent:

$ js js> -(2 ** 2) -4 js> -Math.pow(2, 2) -4 js> (-2) ** 2

4 js> Math.pow(-2, 2)

4 js>

# Claude Pache (8 years ago)

Le 14 oct. 2016 à 16:52, Rick Waldron <waldron.rick at gmail.com> a écrit :

Python is also inconsistent:

pow(-2, 2) 4

-2 ** 2 -4

This is not inconsistency, but that follows from operator precedence rules (those used in mathematics, not in C).

In the same vein, you have pow(1+1, 2) == 4 but 1+1 ** 2 == 2, because the latter is interpreted as 1+(1 ** 2).

# Leo Balter (8 years ago)

If -2 ** 2 returned me -4 in JS I would be confused.

JS is not a math language, it's a programming language. We have basic math operations on its syntax and that's fine.

In the same vein, you have pow(1+1, 2) == 4 but 1+1 ** 2 == 2,

because the latter is interpreted as 1+(1 ** 2).

Where is this going to? Am I supposed to read the 1+1 ** 2 == 2 is a sugar for pow(1+1, 2)? that's not my reading.


Python does not follow a standard implemented in many different implementations governed by different ppl and orgs. Any behaviour, even the unexpected, becomes a feature, it's an easy field and canvas. I'm glad JS aims for a consistent and unambiguous path, even if that can't make everyone loving the syntax.

# medikoo (8 years ago)

I must say throwing here, instead of relying on math dictated operators precedence looks really bad. It's very surprising to those well experienced with the language, and totally inconsistent with how operators worked so far (there is no previous case where one will throw for similar reason).

Also argument that it's inconsistent with Math.pow(-2, 2), is total miss in my eyes. I believe to most programmers Math.pow(-2, 2), translates to (-2)**(2) and not to -2**2, same as Math.pow(a ? b : c, 2) intuitively translates to (a ? b : c)**(2) and not to a ? b : c**2

-- View this message in context: mozilla.6506.n7.nabble.com/Power-operator-why-does-2-3-throws-tp359609p359731.html Sent from the Mozilla - ECMAScript 4 discussion mailing list archive at Nabble.com.

# medikoo (8 years ago)

There are many other cases when with no parens involved, people have different expectations on the outcome. If expression looks ambigous the actual result always depends on operators precedence, it's how language worked for years, and I don't remember any big problems due to that.

Jordan Harband wrote

It's quite simple (as has already been stated): some people expect -x ** y to be -(x ** y). Some expect it to be (-x) ** y.

The early SyntaxError ensures that nobody is confused - programmers will immediately add parens to disambiguate.

Avoiding a potential footgun for the next 50 years, at the insignificant cost of adding two characters so that it parses seems like a very cheap price to pay.

On Tue, Oct 18, 2016 at 12:20 AM, medikoo <

medikoo+mozilla.org@

wrote:

I must say throwing here, instead of relying on math dictated operators precedence looks really bad. It's very surprising to those well experienced with the language, and totally inconsistent with how operators worked so far (there is no previous case where one will throw for similar reason).

Also argument that it's inconsistent with Math.pow(-2, 2), is total miss in my eyes. I believe to most programmers Math.pow(-2, 2), translates to (-2)**(2) and not to -2**2, same as Math.pow(a ? b : c, 2) intuitively translates to (a ? b : c)**(2) and not to a ? b : c**2

-- View this message in context: mozilla.6506.n7.nabble. com/Power-operator-why-does-2-3-throws-tp359609p359731.html Sent from the Mozilla - ECMAScript 4 discussion mailing list archive at Nabble.com.


es-discuss mailing list

es-discuss@

mail.mozilla.org/listinfo/es-discuss


es-discuss mailing list

es-discuss@

mail.mozilla.org/listinfo/es-discuss

-- View this message in context: mozilla.6506.n7.nabble.com/Power-operator-why-does-2-3-throws-tp359609p359733.html Sent from the Mozilla - ECMAScript 4 discussion mailing list archive at Nabble.com.

# Jordan Harband (8 years ago)

It's quite simple (as has already been stated): some people expect -x ** y to be -(x ** y). Some expect it to be (-x) ** y.

The early SyntaxError ensures that nobody is confused - programmers will immediately add parens to disambiguate.

Avoiding a potential footgun for the next 50 years, at the insignificant cost of adding two characters so that it parses seems like a very cheap price to pay.

# Steve Fink (8 years ago)

If tc39 wanted to implement it one way or the other, they would indeed use precedence. The problem is that the precedence of unary '-' vs binary '**' is ambiguous between different people's heads -- not just a little, but a lot. So whichever precedence you pick, some people will be very surprised. It will be obviously wrong to some people, and obviously correct to others.

No matter how good your mechanism is, it can't fix a policy problem.

# medikoo (8 years ago)

ES is already not free from such cases, e.g. !'property' in object will also not resolve as most will expect.

I understand and agree that case is ambigous and is problematic. It just feels very controversial to me that it was decided that this case will be handled differently than others that share exactly same problem.

For those who are not aware of all such quirks/inconsistences it leaves feeling that language is unpredictable in its behaviors.

# Kevin Smith (8 years ago)

It's a committee-compromise grammar hack.

# Claude Pache (8 years ago)

The existence of traps in the language is not an argument for adding other ones. On the contrary, we must learn from previous problematic design decisions, in order not to repeat the same errors.

Also, the language feeling more quirky is less a severe issue than the language inducing to produce more bugs.

# Tom Mitchell (7 years ago)

This "should" be correct in the context of correct mathematics. Expectations and correctness must bias toward correctness. Math/Algebra has been one of the weak points of the web so it makes sense to toss an error and demand the programmer make his intention clear. It also helps with testing to have the programmer add clarity. Still both positive and negative values of x need testing. Some folk generate code with programs and scripts emitting strings and would likely see value in the error to avoid odd things. They should also comment...

Wikipedia seems to have it discussed well: "The minus sign () has three main uses in mathematics:[11] en.wikipedia.org/wiki/Plus_and_minus_signs#cite_note-11

  1. The subtraction en.wikipedia.org/wiki/Subtraction operator: A binary operator en.wikipedia.org/wiki/Binary_operator to indicate the operation of subtraction, as in 5 − 3 = 2. Subtraction is the inverse of addition.

  2. Directly in front of en.wikipedia.org/wiki/Sign_(mathematics) a number and when it is not a subtraction operator it means a negative number en.wikipedia.org/wiki/Negative_number. For instance −5 is negative 5.

  3. A unary operator en.wikipedia.org/wiki/Unary_operator that acts as an instruction to replace the operand by its additive inverse en.wikipedia.org/wiki/Additive_inverse. For example, if x is 3, then −x is −3, but if x is −3, then −x is 3. Similarly, −(−2) is equal to 2. The above is a special case of this."

    en.wikipedia.org/wiki/Plus_and_minus_signs#Minus_sign