JavaScript exponentiation unary operator design decision - javascript

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.

I don't understand this design decision.
Read more about it at https://esdiscuss.org/topic/exponentiation-operator-precedence, https://esdiscuss.org/topic/power-operator-why-does-2-3-throws, https://github.com/rwaldron/tc39-notes/blob/master/es7/2015-09/sept-23.md#exponentiation-operator and https://github.com/rwaldron/tc39-notes/blob/master/es7/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 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.

Related

Result of -1%7 is different in javascript(-1) and python(6)

The expression -1 % 7 in JavaScript is giving me -1 as the result. Whereas in Python and Haskell, I found the result to be 6.
Can anyone explain why both have different behaviors? Which one is correct?
I'm going to give a slightly different answer. As others have said, functions can do whatever you define them to and m - x = -x mod m. As a prelude, I'll note that Haskell has two "mod" functions, mod and rem which differ in just this aspect. You can make a case that the mod one is preferable mathematically. The rem one corresponds to what you'd get on an x86 processor. There is, in fact, a third one, the Euclidean one, which may be even better as well as described by Raymond Boute in The Euclidean Definitions of the Functions Div and Mod. The third form always returns a positive modulus. (There are, in fact, at least two other choices that can be made.)
So, Javascript's definition is what you get from most machine mod opcodes. In this sense, it might be preferable as this would make it more efficient to implement. Mathematically, Haskell's and Python's definition is better than Javascript's. There's also a third definition which may be slightly better.
One key property that the Euclidean and Haskell/Python definitions both possess is x mod m = y mod m is equivalent to x = y mod m which Javascript's definition lacks. You can verify by calculating 6 % 7 in Javascript.
Both are correct. Some languages return positive modulo numbers, while others retain their sign.
You can simply add the modulus to your variable to get a positive number, or check if the number is positive or negative before performing the modulus operation and correct the result after to switch between the two.
Pseudocode to convert a%b between the two:
In a language where -1%7 == -1, you do this to get a positive number:
((a%b)+b) % b
And in a language where -1%7 == 6 you can do this to get the signed version:
if a < 0:
return (a%b)-b
else:
return a%b
Both are correct, they just use different conventions regarding the handling of negative operands. For positive numbers, the conventions coincide, but for negative numbers they do not. In Python a % b always has the same sign as b.
In what follows, I'll use Python notation, where // is used for integer division.
Let
q, r = a // b, a % b
Then
a == q * b + r
must be true in any language (assuming a and b are integers, with b not equal to zero). So the way the remainder is handled has to be consistent with the convention used for integer division. In Python, integer division is floor division, i.e., the result is rounded towards negative infinity. In some other languages rounding towards zero is used instead. And in some languages, you get whatever convention the CPU manufacturer decided to implement, so the same code run on different hardware can give different results. As you can imagine, that can be somewhat annoying. :)
The % stands for different operators in JavaScript and in Python.
In JavaScript, the % stands for the Remainder operator. The documentation already points out the difference between the remainder and the modulo operation:
The remainder operator returns the remainder left over when one operand is divided by a second operand. It always takes the sign of the dividend, not the divisor. It uses a built-in modulo function to produce the result, which is the integer remainder of dividing var1 by var2 — for example — var1 modulo var2. There is a proposal to get an actual modulo operator in a future version of ECMAScript, the difference being that the modulo operator result would take the sign of the divisor, not the dividend.
(Emphasis by me)
In contrast to that: In Python, the % stands for the modulo operator. The documentation also makes a statement about the sign:
The % (modulo) operator yields the remainder from the division of the first argument by the second. The numeric arguments are first converted to a common type. A zero right argument raises the ZeroDivisionError exception. [...] The modulo operator always yields a result with the same sign as its second operand (or zero); the absolute value of the result is strictly smaller than the absolute value of the second operand [2].
(Emphasis by me)
Both are correct.
To complete the other answers, you can also consider the divmod function in Python:
Take two (non complex) numbers as arguments and return a pair of numbers consisting of their quotient and remainder when using integer division. With mixed operand types, the rules for binary arithmetic operators apply. For integers, the result is the same as (a // b, a % b). For floating point numbers the result is (q, a % b), where q is usually math.floor(a / b) but may be 1 less than that. In any case q * b + a % b is very close to a, if a % b is non-zero it has the same sign as b, and 0 <= abs(a % b) < abs(b).
>>> divmod(-1, 7)
(-1, 6)

Javascript: Changing a positive number to a negative?

I have been trying to do the following - change a positive to a negative number.
It appears there are a number of ways to do this. There is the standard
x *= -1
or just placing a negative sign in front the variable i.e if x = 5, then -x is equal to -5.
This seems a great shorthand but wanted to know what the difference is, I can't find any documentation regarding this shorthand on MDN.
I assume there are other ways too.
Probably a basic question but it is annoying not understanding this apparent shorthand.
Any ideas ?
Unary operators in Javascript are basically shorthand functions. You can find the documentation for the Unary (-) here
The - takes in one argument. The number you pass to it. Under the hood, I'm guessing it multiplies it by -1 and returns the product. The function could be written along the lines of:
function -(arg) {
return arg * -1;
}
This is conjecture though. Will need to go through V8's codebase to know for sure.
Update:
So from further research I figure that it's instead of multiplication by -1, it could be a simple sign change. I referred to V8's implementation but that proved to be a dead end because I suck at C++, but upon checking ECMA's specs and the IEEE 754 specs defined here in Steve Hollasch's wonderful blog, I am leaning towards a inversion of the sign bit. All Javascript numbers are 64 Bit IEEE 754 FLoating Points, they can be represented like so:
SEEEEEEE EEEEMMMM MMMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM
Where S is the sign bit. So it looks like the Unary - just flips the sign bit.

What is this asm style "x | 0" some javascript programmers are now using?

I've seen some performance critical javascript code, like the one on this project that makes extensive use of bitwise OR operations with 0. Ex:
GameBoyAdvanceCPU.prototype.write8 = function (address, data) {
address = address | 0;
data = data | 0;
this.memory.memoryWrite8(address | 0, data | 0);
I know about the use case of flooring numbers with "|0", but that isn't the case here, as these are always int's. It looks a bit like asm.js, is this to tell the js engine that we are working with integers, allowing some optimizations? If so, which browsers will make those optimizations?
Any pointers to how this works would be appretiated.
According to JavaScript Performance for Madmen
Wrapping integer arithmetic expressions in ( ) | 0 allows the runtime to be sure that you're doing integer arithmetic instead of floating-point arithmetic. This allows it to avoid checking for overflow and produce faster code in many cases.
and according to the page, it's true for "most" Javascript runtimes, but doesn't say which.
As a second source, Writing Fast JavaScript For Games & Interactive Applications states
To tell JavaScript engine we want to store integer values [...] we could use bitwise or operator:
and a third source from Microsoft's Writing efficient JavaScript page:
[...] explicitly tell the JavaScript runtime to use integer arithmetic [...] use the bitwise or operator
Also, apart from in comments, none of the pages above mention asm.js, so I suspect such optimizations apply in code not explicitly marked as asm/in browsers that don't explicitly recognize it.
Referencing the Ecmascript 5 spec: 11.10 Binary Bitwise Operators, namely
The production A : A # B, where # is one of the bitwise operators in
the productions above (&; ^; |), is evaluated as follows:
Let lref be the result of evaluating A.
Let lval be GetValue(lref).
Let rref be the result of evaluating B.
Let rval be GetValue(rref).
Let lnum be ToInt32(lval).
Let rnum be ToInt32(rval).
Return the result of applying the bitwise operator# to lnum and rnum. The result is a signed 32 bit integer.
And noting that ToInt32() is defined as
Let number be the result of calling ToNumber on the input argument.
If number is NaN, +0, −0, +∞, or −∞, return +0.
Let posInt be sign(number) * floor(abs(number)).
Let int32bit be posInt modulo 2^32; that is, a finite integer value k of Number type with positive sign and less than 2^32 in magnitude such that the mathematical difference of posInt and k is mathematically an integer multiple of 2^32.
If int32bit is greater than or equal to 2^31, return int32bit − 2^32, otherwise return int32bit.
It then logically follows (which you can confirm in your own console) that for example
((Math.pow(2, 32)) + 2) | 0 === 2
(Math.pow(2, 31)) | 0 === -2147483648 === -(Math.pow(2, 31))
And so forth.
Shortly put, the operation turns the number to a 32-bit integer (which has its knacks, see the second example above and the ToInt32() definition for an explanation) and then does a logical or with zero which doesn't change the output beyond the first conversion.
Essentially it's a very cost-efficient way to turn a number into a 32-bit integer because 1) it relies on browser's built-in ToInt32(); and 2) ToInt32(0) short-circuits to 0 (see the spec above) and therefore adds practically no additional overhead.
What it actually does can be seen in this fiddle
It's probing the variable against integer type in this case and either "flooring" or set it to 0 if not an integer.
Thus, there's a tremendous differnece to a = a || 0 which would leave a value of 3.2 untouched.
| operator is bitwise OR. It's used to do a bit by bit OR operation on two integers.
The usage here is a shortcut very similar to logical OR || operator to provide default value, with the exception that the result is integer only (as opposed to string...etc)
address = address | 0;
means "if address is a number, let's use it; otherwise, set it to 0".

What is "MultiplicativeExpression" means?

I was reading the EcmaScript6 specifications and in the Arithemetic operator section ( http://www.ecma-international.org/ecma-262/5.1/#sec-11.6.1 ) its mentioned like this
AdditiveExpression :
MultiplicativeExpression
AdditiveExpression + MultiplicativeExpression
AdditiveExpression - MultiplicativeExpression
What does this mean ?
An expression of multiplication or division.
See Section 11.5
From MDN article on Expressions and operators:
An expression is any valid unit of code that resolves to a value.
So in this case a MultiplicativeExpression is any unit of code that results in multiplication. Most commonly it involves the * operator.
You can read the Annotated EcmaScript as it contains some helpful links on top of the spec.
It means that the ECMA specification is written in Martian. Or by Martians. Or for Martians. I've never been too sure, exactly.
Err, but more helpfully, section 11.6.1 explains how the "addition operator" (what we primitive humans usually call the plus sign or just "+" or "+/-") should treat the result of statements of addition, subtraction, multiplication, division, modulus division, and even string concatenation.
In the header you quote, the writers are calling attention to the various statement types they are trying to define, which is both the simple and more complex case of multiple statements that must be combined (as with the last two lines).
Later in the section it defines how 'hinting' should be handled, in what cases the script should treat variables as numbers instead of strings, etc.
It's just a really esoteric way to put it.

Bit-tweaking in Javascript

Just curious. I did a program in C, with quite an amount of bitwise operations for a variable which defines access controls for a page. I wanna be able to do the same in Javascript only. How can i accomplish this ordeal?
Any help in bit-tweaking in Javascript will help. Remember no costly functions allowed.
JavaScript has the usual assortment of bitwise operators, |, &, ~, etc.; details in the specification.
The following sections will be particularly useful:
Section 11.4.8: Bitwise NOT (~)
Section 11.7: Bitwise Shift Operators (<< and >>)
Section 11.10: Binary Bitwise Operators (| and &)
Note that JavaScript's numbers are all floating point (see Section 8.5, The Number Type, in the specification), but the bitwise operations are defined in terms of integers. So for instance, the definition of the bitwise NOT operator:
11.4.8 Bitwise NOT Operator ( ~ )
The production UnaryExpression : ~ UnaryExpression is evaluated as follows:
1. Let expr be the result of evaluating UnaryExpression.
2. Let oldValue be ToInt32(GetValue(expr)).
3. Return the result of applying bitwise complement to oldValue. The result is a signed 32-bit integer.
Any decent implementation will be able to handle these efficiently, avoiding unnecessary conversions from Number to internal integer and back.
JavaScript has bitwise operators like other languages. Bitwise operators are, by definition, efficient. You should be able to replicate all the bitwise operations performed in your C program in JS as well.
http://www.eecs.umich.edu/~bartlett/jsops.html

Categories