6 ms·
Most (non-strongly-typed?) languages have weird edge cases of this sort. There's a very funny presentation by Gary Bernhard highlighting some of these for Ruby/
by kilburn 6y ago
Most (non-strongly-typed?) languages have weird edge cases of this sort. There's a very funny presentation by Gary Bernhard highlighting some of these for Ruby/Javascript: https://www.destroyallsoftware.com/talks/wat https://www.destroyallsoftware.com/talks/wat
If you look hard enough, you'll probably find some site that shows surprising behaviors of your favorite language. Examples:
Python: https://github.com/cosmologicon/pywat https://github.com/cosmologicon/pywat
Javascript: https://loomcom.com/blog/0097_the_wats_of_javascript.html https://loomcom.com/blog/0097_the_wats_of_javascript.html
Ruby: https://idiosyncratic-ruby.com/29-limitations-of-language.html https://idiosyncratic-ruby.com/29-limitations-of-language.ht...
- akiselev 6y agoThe issue is coercion sanity - not that PHP or JS are sane by any other standard to begin with. You can do `0 == "0"` in Javascript (try it now in the devtools console) and it'll coerce the right hand based on the left hand using parseInt/parseFloat, just like PHP. What it won't do is parse the string "foo" as a zero, which is insane even by Javascript standards. `parseFloat("foo") == parseFloat("foo")` and `parseInt("foo") == parseInt("foo")` in Javascript evaluate to false which is the sane thing to do. `NaN != NaN` is part of the IEEE 754 floating point standard, which predates every single one of the languages you mentioned. We're all competing in the olympics of suffering, so none of us should be promoting this shit :)
- jorams 6y agoIt's important to note here that PHP is converting to an integer, while JS is converting to a double. Integers don't have NaN as a concept. JS doesn't have integers, but if it did it would probably make the same kind of mistake. (This is a guess of course, but a reasonable one given the other insane conversions it does.)
- xapata 6y agoPython may have Wats, but C has Nasal Demons. https://en.m.wikipedia.org/wiki/Undefined_behavior#Examples_in_C_and_C++ https://en.m.wikipedia.org/wiki/Undefined_behavior#Examples_...
- realharo 6y agoBash: https://stackoverflow.com/questions/7577052/bash-empty-array-expansion-with-set-u/61551944 https://stackoverflow.com/questions/7577052/bash-empty-array...
- pdimitar 6y agoAnd? None of it should be condoned. It's all bad. How is that any argument?
- shawnz 6y agoI think it is good and should be condoned. Sometimes having simple rules with the occasionally strange outcome is better than having a complicated set of rules to achieve a simple set of outcomes.
- mikehall314 6y agoI love the "Wat" talk. I wrote a blog a few years ago where I attempted to dig into the JavaScript cases Gary's cites and figure out what is actually happening. https://medium.com/@mikehall314/wat-s-happening-a-closer-look-at-wat-b7f689d33945 https://medium.com/@mikehall314/wat-s-happening-a-closer-loo...
- croo 6y agoJava: jshell> Long a = 12l; Long b = 12l; a ==> 12 b ==> 12 jshell> a == b $3 ==> true jshell> a = 54321l; b = 54321l; a ==> 54321 b ==> 54321 jshell> a == b $6 ==> false ¯\_(ツ)_/¯
- gtsteve 6y agoReally? Not being a Java guy, what is the explanation for this? Terms like boxing and reference comparison come to mind but I can't stitch them into a narrative to explain this.
- Twisol 6y ago`Long` is a boxed (reference) type, but small numbers are interned so you get the same reference when boxing a primitive value. Larger numbers aren't interned, so you get fresh boxes. https://stackoverflow.com/questions/1700081/why-is-128-128-false-but-127-127-is-true-when-comparing-integer-wrappers-in-ja https://stackoverflow.com/questions/1700081/why-is-128-128-f...
- croo 6y agoReference comparison it is with a twist: the jvm caches the most common integers. You'll get the same object from -128 to +127 when implicitly assigning value. This is part of the spec, and can be set to a larger pool with -XX:AutoBoxCacheMax (but cannot be turned off). If you explicitly ask for a new object (Long a = new Long(123l);) you will get a new object and the comparison will fail as expected. The moral of the story is to always use .equals().
- searchableguy 6y agoAre there real use cases for type coercion?
- shawnz 6y agoFor example, it is helpful to avoid having to do tons of explicit integer parsing when working with the DOM, which uses strings for everything
- occamrazor 6y agoYes. You have a list of floats and you want to add n to the n-th element. Then n is both an integer (when indexing the list) and a float (when adding). Of course the language can require an explicit cast, but in most cases it goes against the intuitiveness and simplicity that dynamic languages want to achieve.