7 ms·
WTFJS?
- techiferous 17y agoThis is awesome. <shameless plug> I feel compelled to mention my WTF JavaScript library, even though it is something completely different: http://github.com/techiferous/wtf-js/blob/master/javascripts/wtf.js http://github.com/techiferous/wtf-js/blob/master/javascripts... It's a library for dealing with World Time Format conversions: http://worldtimeformat.com/ http://worldtimeformat.com/ </shameless plug>
- tedunangst 17y agoFloating point is hard, let's go shopping.
- mrcharles 17y agoNaN === NaN being false is extremely handy. If you are trying to track down a rogue NaN in some code, equating a variable against itself finds it immediately. This is also the same in most other languages (I use it all the time in C++).
- kilian 17y agoI didn't know that! very useful, thank you.
- mrcharles 17y agoNo problem. At least once per game I end up having to track rogue NaNs. Learned this trick a while back and it has saved my bacon many a time.
- rflrob 17y agoIs there an advantage to doing that as opposed to using isNaN()?
- mnemonicsloth 17y agoIIRC, it's a speed hack in the IEEE floating point standard. NaN can happen for a lot of different reasons. You might have divided by zero because your code is broken, or you might have divided by epsilon because your algorithm isn't stable on this problem. [1] This test checks to make sure none of {f, g, x, y, intermediate_values} were ever NaN, wihtout having to test each one every step of the way. if ( f(x) == g(y) ) Which is a big deal if it's the guard on an inner loop in some numerical code. [1] I'm fuzzy on the details. Corrections solicited.
- deleted 17y ago[deleted]
- endtime 17y agoIf it's just a debugging trick, though, then speed hacks seem less useful.
- natep 17y agoHow do you know isNaN() doesn't use this fact? In Java, the body of isNaN(n) is simply 'return n!=n;'
- cdavid 17y agoIt depends on the implementation. In C, it is quite easy to have n != n optimized away when compilers have their compiler flags set on. That's why you should use isnan to test nan instead of any other techniques when using C or C++.
- grayrest 17y agoisNaN() will return true for anything that can't be coerced into a number while !(x == x) will only be true for the NaN value itself.
- jrockway 17y agoI am no fan of Javascript, but most of these WTFs make sense to me. The 111111111100 one is unexpected, although there is probably a good explanation. (Like "alert takes a string, you passed a number. nasal demons.")
- mrcharles 17y agoWouldn't that have more to do with the fact that javascript uses floats for everything? It's probably exceeding precision at a guess.
- malkia 17y agoIs it? I thought Javascript has integer type. Say for example Lua (by default) is configured to use only double. It can be configured to use single-float, or even integer - but only one numeric type.
- pmjordan 17y agoStandard JavaScript uses doubles everywhere. They get casted to 32-bit signed integers for bitwise operations, the results are casted back. It's a little odd, but consistent at least.
- mrcharles 17y agoAh. I don't know the inner workings of Javascript so I'm not surprised I was wrong. Just at a glance, that problem to me screams floating point limitation.
- olliej 17y agoA reasonable number of these "wtf"s are just more examples of people failing to understand floating point. sigh
- kevingadd 17y agoThe question is who failed to understand floating point: The authors of the JS specification, the authors of the JS runtime, or the people writing the javascript that demonstrates the 'wtf'? Is the answer "all three"?
- jluxenberg 17y agoThe real WTF is, why does a person writing some Javascript code need to understand floating point? What high-performance calculations are you doing in you Javascript wouldn't be easier, more accurate, and not that much slower using fixed point math?
- mbrubeck 17y agoWith fixed point or arbitrary-precision math, you either need to (a) set the level of precision explicitly, which is just as bad about forcing the user to understand the underlying model, or (b) have the language choose the level of precision heuristically, and have even more unpredictable performance and rounding characteristics. There's no language that lets you do real-world work with numbers like sqrt(2) or PI without understanding precision and representation to some degree.
- tumult 17y agoJavaScript's brilliant solution is to just not have integers. At all. That's better, somehow?
- mbrubeck 17y agoNo, I think JavaScript's "floats everywhere" is worse than most languages. I prefer languages like Python/Ruby that have one arbitrary-precision integer type and one floating point type, or languages like Haskell or Lisp that have a rich selection of floating/fixed/abitrary/rational types with well-defined performance. But some (not all) of the WTFs here exist in all of those languages too. Eventually, programmers working with numbers really do need to learn how to use different numerical representations.
- deleted 17y ago[deleted]
- Tichy 17y ago"(x=[].reverse)() === window // true" Didn't understand this one at first, but I guess it is easy: first x becomes the reverse function of arrays, then it is called with this === window. So it amounts to window.reverse(). Just looked it up, and reverse() works in place, so window.reverse() === window - although it is potentially different from before.
- andreyf 17y agoNo, it amonts to Array.prototype.reverse.call(window) - window doesn't have a reverse method AFAIK, so window.reverse() will raise a TypeError (since you can't call something "undefined").
- Tichy 17y agoare you sure? i thought in js functions are not really tied to "their" object, instead they receive an implicit this argument. wouldn't x belong to window here? that is, window doesn't have reverse, but now it has x
- est 17y agoI smell a potential DOM injection XSS here.
- meastham 17y agoNaN === NaN is guaranteed to be false by IEEE 754. Hardly a wtf. Actually most of these posts seem to be the author misunderstanding floating point numbers. Perhaps he should learn what he's doing before he blames the language.
- kevingadd 17y agoThis suggests that you don't actually know what the === operator is. To summarize: == - 'values are equal' - in this case, are these two numbers equal? The IEEE spec would say no. I agree! === - 'both sides are exactly the same' - or, in more technical terms, are both the values and types of each argument exactly identical. In this case, the answer is yes, absolutely. === is not a numerical comparison and should not be.
- meastham 17y ago=== means value and type are equal. In this case, the types are equal, but the values are not. I'd argue that NaN === NaN being true would imply a broken implementation of IEEE 754, and the designers of JS seem to agree with me.
- kevingadd 17y agoWhat benefit is created by having a hierarchy of comparison operators in which there is no actual way to compare two numbers for semantic (not numeric) equivalence? If (NaN == NaN) == false, and (NaN === NaN) == false, how would you implement an isNaN() function? If your answer is 'depend on the VM', I find that a bit strange.
- brianleroux 17y agoEh, msg me on twitter (same username) if you have better wtfs or want to contribute. The idea isn't to prove how awesome knowledgeable you are but rather to have a good laugh and MAYBE point out some of the less intuitive aspects of the language we all love to hate on.
- icefox 17y agoJust pick up JavsaScript: The Good Parts by Douglas Crockford. He has a chapter called "The bad parts".
- jetako 17y agoisNaN(null) == false; is the only wtf I can never remember to avoid, because I can't rationalize it no matter how hard I try. Edit: I get it now. null coverts to 0
- waldrews 17y agoIn what language is 0.1 + 0.2 == 0.3? (I guess C# with decimal literals, but you'd have to specify that with a suffix)
- twopoint718 17y agoI was curious and fired up sbcl: * (= (+ 0.1 0.2) 0.3) T * (type-of 0.1) SINGLE-FLOAT * (= 0.3d0 (+ 0.1d0 0.2d0)) NIL * (type-of 0.1d0) DOUBLE-FLOAT
- techiferous 17y agoIn Ruby: 0.1 + 0.2 == 0.3 => false According to "The Ruby Programming Language", all languages that use IEEE-754 floating-point numbers have this problem. In Ruby you can get around this by using BigDecimal. >> require 'bigdecimal' => true >> require 'bigdecimal/util' => true >> 0.1.to_d + 0.2.to_d == 0.3.to_d => true
- martian 17y agoIn Python >>> decimal.Decimal(".2") + decimal.Decimal(".1") == decimal.Decimal(".3") True >>> .2 + .1 == .3 False
- Locke1689 17y agoPrelude> (0.1 + 0.2) == 0.3 False Prelude Ratio> 1 % 10 + 2 % 10 == 3 % 10 True
- jrockway 17y agoOr: ghci> 0.1 + 0.2 == (0.3 :: Ratio Int) True Same type, less syntax.
- regularfry 17y agoThat's cheating. Haskell isn't a language, it's The Word of Simon. The question of which Simon is left as an exercise to the reader.
- pixelcort 17y ago`typeof null` is 'object', not Object. (It's a string that contains the word object.)
- invisible 17y agoIf the programming can't handle a null object, check that the object is of the required type (by setting a key) or check that the object is not null. It's dumb to expect null to not be an object when EVERYTHING is an object in JS (except undefined, which is special). Furthermore, the programmer would be setting a value to null if they are checking for null (are there any other instances where null occurs without explicitly setting?).
- statictype 17y ago>(function(){ if(false) var window; return window }()) === window >JavaScript interpreter checks all variable declarations in scope before execution. This is another way of saying that all variable declarations are scoped at the function level, not the individual block level. This is why generating closures in a loop is broken in javascript (Although in just about every other language as well, closures in a loop give surprising results at first - including, I think, arc?) To get a new scope, you have to use the anonymous function trick: (function(){ var x;//new scope ... })()
- andreyf 17y agoThis is not a WTF if you just know where a language draws scope boundaries - for most languages, it isn't just along the {}'s.
- statictype 17y agoIt's a WTF in the sense that every other language with curly braces scope at the block level.
- kwamenum86 17y agoWhen you run reverse with a context of anything besides an array you end up getting back that context. This is why assigning [].reverse to x, then running x() returns window. It is an interesting quirk. Not sure if this is the js specified behavior though.
- andreyf 17y agoYes, this is JS specified behavior. If there is no activation object (one referenced by an identifier before the `.'), the value of `this' is set to the global object.
- invisible 17y agoA bit of Computer Science knowledge would go a long way in explaining these: e.g. "Foo" + + "Bar" === "FooNaN" (attempting to do unary + on "Bar"). Tons of other examples as documented here, but some of these are a "bit" strange yes ;).
- andreyf 17y agoPsht, floating point WTF's are for noobs. == is where the money is at. Straight from my V8 console: >>> x = new Boolean; false >>> b = (x || !x); false >>> Boolean(b == false) && Boolean(x == false) && Boolean(b) && Boolean(x) true
- nandemo 17y agoWTFHN? Why is this voted up? Just because you don't immediately understand something doesn't make it a WTF.
- tszming 17y agoFYI, Some guy registered WTFPHP.com on 2010/02/12
- tmountain 17y agoEh, no biggie, a few pages of gotchas. If we were talking about PHP, I could write a few volumes.