Recently I learned that in Javascript, [5 * 5] * 2 // 50 [5 + 5] * 2 // NaN 1 + [5 * 5] * 3 // 76 1 + [5 * 5] - 1 // 124 Interestingly, even Typescript will not ( by default ) catch this class of bugs.
Why ['1', '7', '11'].map(parseInt) returns [1, NaN, 3] in JavaScript
101–110 of 163 posts
Re: Why ['1', '7', '11'].map(parseInt) returns [1, NaN, 3] in JavaScript
#102Earlier quoted context omitted.
It may be logical but: - I know all that, have been programming for 15 years, yet I still would have done the mistake. - Simple unit tests may very well not catch this bug the first time. - The language design allows your brain to ignore the index parameter because JS accepts superfluous parameters, which is a terrible decision. - map() is a mapping primitive. It's supposed to adapt a type to another type so that you…
> - The language design allows your brain to ignore the index parameter because JS accepts superfluous parameters, which is a terrible decision. Without that we would not be able to have variable length argument lists in the past.
Spread has existed in Python forever under the name of "splat operator", default values as well. Same with ruby.
That what I meant when I said "they accumulate". A bad design decision not only affect the user cognitive load and productivity, but it also cascades to the rest of the language and shapes it.
Re: Why ['1', '7', '11'].map(parseInt) returns [1, NaN, 3] in JavaScript
#103Earlier quoted context omitted.
There's some interesting history for awareness of the first issue: parseInt used to be a notorious source of bugs and so it used to be more common to see it with a second argument on any project which used a linter in that era. ES5 deprecated that behaviour and it's been widespread enough that code which started in the IE9+ era now looks like the very old buggy code omitting the radix, so anyone getting started relat…
I didn't know about the second parameter until I saw it in a TypeScript signature a few months ago, which acted as a sort of warning to me to avoid using it incorrectly. But TypeScript doesn't catch this specific bug because it's technically correct [1] from an API stand-point, as the second parameter to parseInt is a number and the second argument to map's callback is a number. For as many situations as TypeScript g…
Re: Why ['1', '7', '11'].map(parseInt) returns [1, NaN, 3] in JavaScript
#104This isn't strange or surprising. parseInt takes two arguments, the second one is the radix and map will call with three arguments, the value, the index and the whole array. You just have to know this and it might be different in other languages. [ ... ].map(x => ...) is the right way to do this.
It may be logical but: - I know all that, have been programming for 15 years, yet I still would have done the mistake. - Simple unit tests may very well not catch this bug the first time. - The language design allows your brain to ignore the index parameter because JS accepts superfluous parameters, which is a terrible decision. - map() is a mapping primitive. It's supposed to adapt a type to another type so that you…
I have not done it with parseInt per se, but I have made this precise mistake at least twice with passing a function `f` with an optional second argument in `some_array.map(f)`, and it took a while to figure out what was happening each time.
Now that Javascript has proper iterables and iterators and generators, I have been enjoying using versions of `map` and `spreadmap` which take in a callback function and iterables and produce an iterator. Then I can explicitly use `enumerate` if I want it. https://observablehq.com/@jrus/itertools#map
Re: Why ['1', '7', '11'].map(parseInt) returns [1, NaN, 3] in JavaScript
#105 ['1', '7', '11'].map(numStr => parseInt(numStr));
I think you'd learn something much more useful with function radixParser(radix) { return numStr => parseInt(numStr, radix); }
['1', '7', '11'].map(radixParser());
> [ 1, 7, 11 ]
['1', '7', '11'].map(radixParser(8));
> [ 1, 7, 9 ]
['1', '7', '11'].map(radixParser(2));
> [ 1, NaN, 3 ]Re: Why ['1', '7', '11'].map(parseInt) returns [1, NaN, 3] in JavaScript
#106Earlier quoted context omitted.
0 is a special case where the parser tries to guess based on how the number is formatted. 1 just doesn't make sense at all. Using 0 is the source of many interesting bugs, like when someone puts in an IP address like so: 192.168.010.001 and the client tells you it can't connect (to 192.168.8.1).
As of ES5 010 must be parsed as 8 if you pass in a radix of 0.
(That behavior contrasts interestingly with IPv6 where the numbers [segments] are only supposed to ever be hexadecimal (Base-16) and leading zeroes are to be ignored.)
Re: Why ['1', '7', '11'].map(parseInt) returns [1, NaN, 3] in JavaScript
#107The extra args passed by map coupled with the optional extra args in standard methods is the cause of a lot of confusion, but this feels like a missed opportunity for demonstrating functional programming. In the end author suggests ['1', '7', '11'].map(numStr => parseInt(numStr)); I think you'd learn something much more useful with function radixParser(radix) { return numStr => parseInt(numStr, radix); } ['1', '7', '…
const radixParser = (radix) => (numStr) => parseInt(numStr, radis);Re: Why ['1', '7', '11'].map(parseInt) returns [1, NaN, 3] in JavaScript
#108This isn't strange or surprising. parseInt takes two arguments, the second one is the radix and map will call with three arguments, the value, the index and the whole array. You just have to know this and it might be different in other languages. [ ... ].map(x => ...) is the right way to do this.
Re: Why ['1', '7', '11'].map(parseInt) returns [1, NaN, 3] in JavaScript
#109This isn't strange or surprising. parseInt takes two arguments, the second one is the radix and map will call with three arguments, the value, the index and the whole array. You just have to know this and it might be different in other languages. [ ... ].map(x => ...) is the right way to do this.
It may be logical but: - I know all that, have been programming for 15 years, yet I still would have done the mistake. - Simple unit tests may very well not catch this bug the first time. - The language design allows your brain to ignore the index parameter because JS accepts superfluous parameters, which is a terrible decision. - map() is a mapping primitive. It's supposed to adapt a type to another type so that you…