Live data from Hacker News

Why ['1', '7', '11'].map(parseInt) returns [1, NaN, 3] in JavaScript

medium.com

41–50 of 163 posts

Re: Why ['1', '7', '11'].map(parseInt) returns [1, NaN, 3] in JavaScript

#41

Earlier quoted context omitted.

This has nothing to do with casts or defaults. Map passes multiple parameters and parseInt accepts multiple parameters. Being unaware of the functions you're using is the problem, not some sort of weird gotchas of the language. The code in the title makes multiple assumptions, and those assumptions all proved wrong.

A typed language would absolutely fail this at compile time.

Only because map's third provided argument exists. If map only supplied element and index to the callback, this would pass most type checkers I'm familiar with, and would remain just as confusing.

Re: Why ['1', '7', '11'].map(parseInt) returns [1, NaN, 3] in JavaScript

#42

Earlier quoted context omitted.

Yeah, I’m not surprised at all by this. I get that there are a lot of weird things in JS but I don’t think this is a JS oddity. Surprise! You need to know the basics of how your language works.

That's apologist talk pure and simple. The language, silently, does something that's almost certainly wrong. The language has enough information to provide you with a helpful warning or error message that you probably don't want to do this, but instead, it violates the principle of least surprise by just doing the wrong thing instead. The correct error is something along the lines of: let numbers = input.iter().map(p…

The map function fully expects a function with two arguments, as per documentation. Why would passing a function that takes two arguments to map be an error?

Re: Why ['1', '7', '11'].map(parseInt) returns [1, NaN, 3] in JavaScript

#43

Earlier quoted context omitted.

Yeah, I’m not surprised at all by this. I get that there are a lot of weird things in JS but I don’t think this is a JS oddity. Surprise! You need to know the basics of how your language works.

That's apologist talk pure and simple. The language, silently, does something that's almost certainly wrong. The language has enough information to provide you with a helpful warning or error message that you probably don't want to do this, but instead, it violates the principle of least surprise by just doing the wrong thing instead. The correct error is something along the lines of: let numbers = input.iter().map(p…

> The language has enough information

No.

> expected function that takes 1 argument

`map` expects a function that takes one, two, or three arguments.

Re: Why ['1', '7', '11'].map(parseInt) returns [1, NaN, 3] in JavaScript

#45
post #4

This 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.

I'd certainly call it unintuitive if you run into it yourself and aren't aware of this, but once you unpack it we've seen it's expected behavior.

Re: Why ['1', '7', '11'].map(parseInt) returns [1, NaN, 3] in JavaScript

#46

Earlier quoted context omitted.

That's apologist talk pure and simple. The language, silently, does something that's almost certainly wrong. The language has enough information to provide you with a helpful warning or error message that you probably don't want to do this, but instead, it violates the principle of least surprise by just doing the wrong thing instead. The correct error is something along the lines of: let numbers = input.iter().map(p…

> The language has enough information No. > expected function that takes 1 argument `map` expects a function that takes one, two, or three arguments.

Well there's your first problem haha.

Re: Why ['1', '7', '11'].map(parseInt) returns [1, NaN, 3] in JavaScript

#47
post #34
post #28

Earlier quoted context omitted.

Those are unfortunately not the same. The second one (with an explicit radix of 10) is correct; the first is not (or is at least a bit riskier). See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe... (ctrl+f for "always").

In most browser implementations (at least all the ones we develop for) it would assume a radix of 10 for those values specifically.

[deleted]

Re: Why ['1', '7', '11'].map(parseInt) returns [1, NaN, 3] in JavaScript

#48
post #40
post #21

Earlier quoted context omitted.

What is the syntactic sugar here? I mostly see a map that doesn't behave how anyone would expect.

The syntactic sugar here is that map and parseInt can be called without specifying all parameters. (But, since JS has no function overloading, it's the same function you're calling.)

Optional/defaulted function arguments are an extremely useful feature of many programming languages; are you arguing that they are always harmful?

Re: Why ['1', '7', '11'].map(parseInt) returns [1, NaN, 3] in JavaScript

#49

>> "If the radix provided is falsy, then by default, radix is set to 10." The official docs for parseInt says this: >> An integer between 2 and 36 that represents the radix (the base in mathematical numeral systems) of the string. Be careful — this does not default to 10. [1] I just found it confusing whether the author meant the default value is 10, or if a falsy parameter (not undefined) turns out to be 10. [1] htt…

So looking at the rest of the documentation, the parameter not being set causes the default radix to be 10 unless the number starts with 0 or 0x, in which case they radix is 8 or 16 respectively. Though newer versions of JS no longer support the octal syntax (it likely just caused bugs for people who had initial zeros in their strings sometimes)

parseInt("0x10") == 16 parseInt("0x10", 10) == 0

Re: Why ['1', '7', '11'].map(parseInt) returns [1, NaN, 3] in JavaScript

#50

Earlier quoted context omitted.

A typed language would absolutely fail this at compile time.

Only because map's third provided argument exists. If map only supplied element and index to the callback, this would pass most type checkers I'm familiar with, and would remain just as confusing.

Yes but with mandatory parameters the programmer would be aware parseInt had a radix in the first place if they had used it even once. That's one advantage of mandatory parameters, but there are of course disadvantages.
Post reply on HN