5 ms·
TIL JavaScipt doesn't have an integer type and uses double under the hood to store integers. Yet another footgun to add to the massive stack.
by umvi 6y ago
TIL JavaScipt doesn't have an integer type and uses double under the hood to store integers. Yet another footgun to add to the massive stack.
- chrisseaton 6y agoDouble represents consecutive integers up to 2^53 - that's even larger than Java's int so it's more than fine for almost all purposes.
- umvi 6y agoI can't help but compare JS to python though. For every footgun in JS, the same footgun does not exist in python including this one.
- jkaptur 6y agoInteresting - I view it the opposite way. In JavaScript, you need to know the details of exactly one numeric type: the regular, standard IEEE 754 float that's used by Java, Python, C++ (generally), and every other programming language under the sun. That's it! There is only one way to do it ;) These days, if you need huge integers, you can use BigInt, but if you want to use it in an expression that also contains floating point values, then you need to explicitly convert it. Explicit is better than implicit.
- umvi 6y agoI just find it counter intuitive, that's all. The expectation is that high level scripting languages have BigInt enabled by default (since that's what Ruby/Python do). Not so with JS. The expectation is that sorting an array of integers in place: [1,3,2,4,5,7,6,8,9,10].sort() produces an array with the numbers in ascending order (since that's what Ruby/Python do). Not so with JS (try it out). A agree there is a perfectly logical reason for every quirky behavior, but I've been surprised (in a bad way) so many times by JS's counter-intuitive behavior that I now have a mental collection of gotchas where JS deviates from expectation.
- chrisseaton 6y agoConsider this: JavaScript actually has a formal specification. Ruby and Python have no formal specification. I can tell you (with reference to the specification) exactly what a JavaScript program does. JavaScript may seem wacky on the surface, but actually it's all worked out. Nobody can tell you what a Ruby or Python program does. And you think JavaScript is the footgun?
- umvi 6y agoWell yes, in theory if all the developers read JS's formal specification JS would be better. But in practice developers just wing it without reading anything, and only go to read things when getting an unexpected result. And so we get the follow outcome - python behaves as expected in more cases than JS behaves as expected. "Theory is great in theory, but in practice, practice is better"
- jkaptur 6y agoI mean, if you define "whatever Ruby and Python do" to be intuitive, then, sure, every other language is going to have "a long list of weird footguns". JS has many quirks, but I like that the numeric representation is extremely simple and explicit (even compared to Python).
- mschuetz 6y agoThat's a problem with the specification of sort, not with javascript using double by default. But yeah, that sort example is seriously bonkers.
- ficklepickle 6y agoArray.sort converts to UTF-16 code units, or some such weirdness, by default. If you are sorting anything other than strings, you will want to pass in a comparison function. [1,3,2,4,5,7,8,9,10].sort((a,b) => a - b) gives you the behavior one would expect. I suppose you already know that, though. Agreed there are lots of quirks.
- recursive 6y agoExcept it also has bitwise operators which is definitely weird.
- ygra 6y agoAnd those bitwise operators are defined to convert the number into a 32-bit signed integer as part of the process. Which is why foo | 0 is a way of converting a number to an integer (as long as it's not too large ...).
- MaxBarraclough 6y agoI agree Python is the better language, but they have quite different origin stories. JavaScript was thrown together in very short order, and has gradually evolved since then. It was a good enough first-to-market scripting language for the browser, got standardised, and has been the client-side scripting language of the web ever since. It's evolved somewhat since its early days but is backward compatible. If I understand correctly, Python had a more considered initial design, and had a clean-break overhaul in Python3, allowing it to evolve without accumulating as much cruft and inconsistency. (Python is famous for its philosophy of there should be one—and preferably only one—obvious way to do it.) People use Python by choice: unlike JavaScript where browsers support no other scripting languages, Python won out over its rivals in fair contest. All things considered, JavaScript isn't that bad. Used correctly it can be elegant and powerful. It has some nasty dark corners, but it generally provides all you need to avoid them, if you know your way around. With modern JIT engines it can even be pretty fast. Its curious use of doubles is just the kind of thing modern JIT engines are able to be smart about, compiling down to use integer operations where possible.
- andreareina 6y agoPython just has its own footguns, like mutable default arguments or how lambdas close over variables in comprehensions.
- pmarreck 6y agoWhile I think everyone can agree this is just yet another terrible design decision in JavaScript, at least there are libraries to give you this, and it looks like BigInt will eventually be native to JS: https://github.com/peterolson/BigInteger.js/ https://github.com/peterolson/BigInteger.js/
- mschuetz 6y ago> While I think everyone can agree this is just yet another terrible design decision in JavaScript I disagree. Double was the best choice they could have made for a dynamically typed language.
- conradludgate 6y agoNot quite true. They do use an integer data representation if the number is an integer, it just silently changes to a float if its necessary. So `let x = 2;` the type would be 'number' but the data would just be an integer.
- Someone 6y agoThat’s an implementation detail. JavaScript, the language, doesn’t (AFAIK; I don’t keep track of this rapidly moving target) have integers (but does have integer arrays, nowadays. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays https://developer.mozilla.org/en-US/docs/Web/JavaScript/Type...) If the type were integer, let x = 2 let y = x / 8 would have y = 0, but its value will be 0.25.
- Smaug123 6y agoThat's perfectly reasonable; there's nothing to say that `/` has type `int -> int -> int` even in a strongly-typed language. I wouldn't bat an eyelid to discover that `/` had type `int -> int -> float` in any language. The problem is when you discover that `+` does not have type `int -> int -> int` (e.g. when you try and increment a very large integer and floating point stops being able to represent it).
- MaxBarraclough 6y ago> I wouldn't bat an eyelid to discover that `/` had type `int -> int -> float` I'd bat both eyelids, that's the kind of surprising design decision that would turn me away from a language. To my knowledge, no major programming language does this, and there's wisdom in the principle of least surprise. edit: I am of course mistaken, Python does exactly this. Corrected by chrisseaton again!
- chrisseaton 6y ago> I'd bat both eyelids, that's the kind of surprising design decision that would turn me away from a language. To my knowledge, no major programming language does this, and there's wisdom in the principle of least surprise. Lol prepare to bat your eyelids. % python Python 3.8.5 (default, Jul 21 2020, 10:48:26) [Clang 11.0.3 (clang-1103.0.32.62)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> 1 / 2 0.5
- evilpie 6y agoJavaScript also has newish BigInt support: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe.... It even has syntax: 42n.
- mschuetz 6y agoGiven that it's a dynamic scripting language, I think double was the best choice they could have made. It gives serious number crunching performance, an integer range up to 2^53, and, of course, double precision floating point math. The only better choice they could have made would have been to make it static/strongly typed with various numeric types.