I'm always seeing | 0 in compiled sources in REPL:

What is it doing? Does it have runtime cost?
/cc @ncave @alfonsogarciacaro
value | 0 = 0 when value = undefined so I think it like a guard against undefined values of integers if they are not initialized, not sure tho :smile:
but why would we do that!?
In JavaScript it transforms a float into a int:
1.000001 | 0 produces 1.
The return type of the factorial function is int, that's a way to ensure it. That's the reason I think.
@xtuc thanks that makes sense!
Let's maybe wait @alfonsogarciacaro's anwser.
It converts a JavaScript number into a 32-bit signed integer with overflow:
2147483648 | 0 // returns -2147483648
And if you want to convert a JavaScript number into a 32-bit unsigned integer with overflow, you can use >>> 0 instead:
4294967296 >>> 0 // returns 0
Hehe, I'm not sure what | 0 does exactly either :wink:
I added it after a suggestion from a user. This is similar to what asm.js does to indicate an expression is an int, and it could give a hint to the JS compiler that the expression doesn't need to be allocated. But I'm not really sure if JS engines can use it for optimization in no asm.js modules 馃
@alfonsogarciacaro Yes the JS engines can optimize it even for regular JS code, not just asm.js
But more importantly, it correctly handles overflow, which would not be handled correctly if you did not use | 0
awesome! good to know /cc @carstenkoenig
thanks for the CC - I heard something like this a while ago (something like cast to int ;) ) - I was just wondering if it would have some performance impact as you don't need the second one in the example above - but I guess it's very minor if it's there at all
One last question: in the compiled source it's doing | 0 twice. But it's only one place where overflow can happen. Is that needed?
@forki The | 0 is needed for integer literals and also every time an operator is used:
500 | 0
(5 + 10) | 0
(5 - 10) | 0
(5 * 10) | 0
(5 / 10) | 0
etc.
I'm not 100% sure if it needs the | 0 on integer literals, but I know it needs them on all mathematical operators.
Looking at your code example, both of the | 0 seem unnecessary.
Instead, it's missing a lot of | 0:
factorial(10 | 0)
loop(n, 1 | 0)
const $var2 = (i - 1) | 0;
acc = (acc * i) | 0;
Also, rather than using (acc * i) | 0 it should use Math.imul(acc, i). The reason is because multiplying two large integers can give the wrong result (because the number is too big), but Math.imul always behaves correctly.
Most helpful comment
@alfonsogarciacaro Yes the JS engines can optimize it even for regular JS code, not just asm.js
But more importantly, it correctly handles overflow, which would not be handled correctly if you did not use
| 0