7 ms·
JavaScript Coercions Grid
- sarcasmOrTears 8y agoDon't worry, it looks scarier than it is
- wongarsu 8y agoI don't really get why `-0 + 0 == 0` is marked as a WTF? I guess getting -0 would be marginally better, but 0 is a perfectly fine answer. I also think `true + 0 == 1` is perfectly reasonable, but I get that this might not be reasonable for everyone. All the other fixes look like genuine improvements.
- detaro 8y agoI think -0 + 0 == 0 is correct IEEE 754 behavior too. Two numbers that only differ in the sign cancel out to +0 when added together.
- lelf 8y agoYep, it is +0 under default rounding direction. But +0 == -0 anyway.
- benmanns 8y agoI made a PR for -0+0 based on your suggestion: https://github.com/getify/getify.github.io/pull/1 https://github.com/getify/getify.github.io/pull/1
- _getify 8y agoThe "WTF" label is not about correctness, it's about surprise/intuition. It doesn't really matter to me whether it's mathematically or IEEE correct. It's strange and inconsistent. Yes, two numbers of different signs added together are supposed to be 0, but... a number is never supposed to change (sign or magnitude) when you add 0 to it, and here it does... so... it's a strange corner case that I think defies intuition. Given the two precedences that are incompatible, I think far more people are likely to think "anything + 0 ======= anything" than they are to think "anything + -anything ========== +0". So that's why I marked it as a WTF.
- jacobolus 8y ago> number is never supposed to change (sign or magnitude) when you add 0 to it In the “real numbers”, zero doesn’t have a sign at all, and -0 and 0 mean precisely the same thing. Floating point is an approximation which needs to make some choices about edge cases, for the sake of practical uses (for instance it is useful to distinguish negative underflow from positive underflow, so there is an extra -0 value included). The behavior that 0 - 0 or -0 + 0 produces 0 as output is not an unreasonable choice (it is what I would expect, as someone with a decent amount of mathematical experience). I would not expect very many people to have the “intuition” that -0 + 0 or 0 - 0 should produce -0 as a result, assuming they had any intuition at all about what should happen in this edge case.
- dnautics 8y ago-0 is truly a mistake on the part of the IEEE committee. You can get it by dividing by -infinity, it's supposed to indicate "zero approached from the left in this case, but it's not consistent; sqrt(-0) will give you -0 in most implementations
- jacobolus 8y ago1/–∞ == –0 seems like obviously the correct behavior in context of IEEE floats. I think if someone is careful it should be possible to make an implementation of complex square root on top of IEEE floats such that √(–a² + 0i) == ai, whereas √(–a² – 0i) == –ai, representing the two sides of a branch cut. Yes, √–0 should be 0. File a bug against whatever implementation returned –0 for that one.
- seanwilson 8y agoJavaScript gets a lot of flak about weird coercions but I never found them a big source of errors compared to say more basic things like forgetting function arguments or getting them in the wrong order. Coercions are way less of a problem in TypeScript as well because coercions that change the type will get flagged at compile time.
- shawnz 8y agoAgreed, These corner cases are weird only because there's basically no sensible thing to do in these situations which would be consistent with the rest of the rules. Since there's no real reason you'd be doing any of these weird coersions I think it's pretty unlikely that they'd result in bugs. It's not fail-fast, but I don't see this stuff resulting in any subtly incorrect behaviors.
- seanwilson 8y ago> there's basically no sensible thing to do in these situations Are there any better options for dynamic languages when a weird coercion is going to be done? Throw an exception? Exit with an error? Convert to some special invalid_coercion value similar to NaN? It's another reason static type checking (i.e. don't let the code run) is a no-brainer to me.
- gruez 8y ago>Throw an exception? Seems like the best choice rather than plowing ahead with assumptions
- jimmaswell 8y agoI feel like it's fine for languages in a web context to take a "the show must go on" attitude as they do. Partially working webpages (slightly broken html/js/etc) are generally much better than a blank page/error message or none of the js working at all.
- shawnz 8y ago
- tuesdayrain 8y agoI'm not entirely sure why all of this even exists, it seems like it creates a lot of potential for bugs. I've been developing in JS for years and I've never intentionally used type coercion. If I ever needed to operate on multiple types I would always explicitly cast them to the correct type beforehand.
- saghm 8y agoI think it's mostly just backwards compatibility at this point; unlike with server-side languages, you can't just bump the major version and let people switch to it at their own pace. No browser is motivated to make breaking changes because there's a chance that they could break existing sites, and from a user's perspective, all they'll see is that site Foo works in Browser A but not Browser B, so Browser A will presumably lose some market share.
- gambler 8y ago>unlike with server-side languages, you can't just bump the major version and let people switch to it at their own pace. That's what strict mode was for.
- baddox 8y agoUsing variables in Boolean expressions (to check whether the value exists) is the one place I (and probably most JS developers) use type coercion. Which can still bite you, especially if you have a zero that you expect to be considered a present value.
- beders 8y agoSometimes I feel like we are living in the wrong timeline. In the right timeline, a deeply flawed language like JavaScript would never have been successful and we would use a decent application delivery mechanism that is platform-sensitive and not a hypertext document browser with a document model unsuitable for interactive apps. But here we are: Never bet against JavaScript
- shawnz 8y agoIt's the epitome of "Worse is Better" :)
- jerrysievert 8y ago> In the right timeline, a deeply flawed language like JavaScript would never have been successful but in that same timeline, we had Java, which was touted to solve all of those problems, vs Javascript which was touted to add slight interactivity. We took a step sideways, instead, with Java offering a lousy user experience for what it promised, and Javascript getting progressively better, while promising nothing in the early days. The other competitor, Flash, ended up flawed in its own right. And here we are.
- ChrisSD 8y agoThe trouble with Java in the browser wasn't the language per se; it was the external runtime. This was also the problem with Flash. It was basically like downloading and running a random exe from any site you visited. From the start Javascript was built in to browsers and even as it grew it was running in the context of a web page. By the time Javascript had grown large enough that people were looking for other languages it had become too entrenched. Besides, Javascript is good enough for most websites. It's only larger web apps where it becomes more of a problem.
- jerrysievert 8y ago> It was basically like downloading and running a random exe from any site you visited. which is pretty much where we are today, especially with wasm and bundles. we just went around the virtual machine and byte code before coming back. from Javascript's start, it was embedded, but Java applets were pretty early as well. The core problem was direct interactivity with the browser, which Javascript had a small amount of initially, and Flash/Java tried to subsume. The difference was how the browser itself was treated.
- deleted 8y ago[deleted]
- DonHopkins 8y agoBrendan Eich never really understood the concept of equality. https://dorey.github.io/JavaScript-Equality-Table/ https://dorey.github.io/JavaScript-Equality-Table/
- teddyh 8y agoSee also: JavaScript Equality Minesweeper: https://eqeq.js.org/ https://eqeq.js.org/
- deleted 8y ago[deleted]
- jacobolus 8y agoTurning +true into 1 and +false into 0 does not seem surprising or problematical. To me this seems like the obviously only correct behavior. Turning these into NaN would be a giant terrible WTF for me. The author might want to add !!foo as an additional type of coercion (to bool).