Live data from Hacker News

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

medium.com

141–150 of 163 posts

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

#141
post #103

Earlier quoted context omitted.

Yeah, the problem this one time isn't typing but the JS developers implementing map wrong. Map should not take two arguments. There should be a different function like enumerate in in python for this.

There's nothing wrong with Array#map passing callback(val, i, array), it's a legitimate feature, and the two other arguments can be omitted in actual callbacks. It just means we need to be aware of how it works, which is basically true about any programming language, any standard library, and basically any kind of tool that any kind of professional uses, whether abstract or literal: know how to use your own tools, an…

> know how to use your own tools, and avoid blaming the wrench because it's a poor excuse for a hammer

This is, of course, why famously machine shops simply put up signs saying “don't touch the whirring metal” rather than using safety guards and similar measures.

I don't disagree that it's useful to have the extra arguments for map but the part which is really deadly is ignoring extra arguments, even if it's obvious why backwards-compatibility made changing it unlikely. I really wish that JavaScript had implemented keyword-arguments when the benefits had become obvious because when features like map were added a decade or two later they could have been defined as passing arguments by keyword and causing an error when given a function which didn't accept those names.

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

#142
post #139

Use Typescript. Regular JS just has too many gotchas to be usable in large applications. You can crank up the settings in TsLint and never worry about things like this again

Did you try testing that? The TypeScript compiler does't say a thing about that code: https://www.typescriptlang.org/play/index.html#src=alert(%5B... TSLint similarly reports nothing even with the tslint:all ruleset: https://palantir.github.io/tslint-playground/?saved=N4Igxg9g... https://palantir.github.io/tslint-playground/

Doesn't seem right, are all the strict compiler options enabled?

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

#143

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 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?

The map function has a bad API surface that interacts poorly with the way people expect it to work. In a better designed API, if you needed the index of each yielded value other languages have some kind of enumerate method that will allow people opt-in to getting the index. Then if you needed the replicate the presented situation you would have something like

    ['1', '7', '11'].enumerate().map(([val, idx]) => parseInt(val, idx))
I understand that this pattern of having extra "helper" arguments is pervasive in JS and might seem less exotic to the community, but I feel it is a problematic approach, as it is foot-gun prone.

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

#144

Earlier quoted context omitted.

> in Python forever under the name of "splat operator" The name “splat” is not commonly used in Python. That name comes from Ruby (or Perl?). In Python it is usually called “star” or similar.

Both are used. Here you can see Steven D'Aprano, one of the dev of the Python stdlib, naming it "splat": https://mail.python.org/archives/list/python-ideas@python.or... I use "splat" all the time myself. On the other hand, itertools.starmap() is named this way because it does: def starmap(func, iterable): for e in iterable: yield func(*iterable) Things rarely have one name in computing. Hell I call curly brackets "mu…

That’s a mailing list email from 2016, and is a joke about bunch of silly non-standard names for punctuation (e.g. “bang”, “wack”, and “twiddle”).

Obviously occasional people are going to pick up terminology from other communities, and the name “splat” has been gaining popularity recently (I had literally never heard that term before a few years ago, and have been writing Python code since 2002). I occasionally hear British expats in the USA calling elevators “lifts” or baby carriages “prams” or lines of people “queues”. Doesn’t mean those have been common American terms.

This was certainly not called the “splat operator” “forever” as claimed in the previous comment.

> I call curly brackets "mustaches" all the time

I have never heard anyone call these “mustaches”. The common terms are “curly brackets” and “braces”. Nobody is going to have any idea what you are talking about.

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

#145
post #91

Earlier quoted context omitted.

Why would you use parseInt over Math.round if you only expect a single arg? Seems like you'd only want to use parseInt if you expect to need radix changes at some point, e.g. converting between hex strings, decimal values, and binary strings ['1', '7', '11'].map(Math.round) // => [1, 7, 11] [["00000001", 2], ["00000111", 2], ["0x0B", 16]].map(x => parseInt(...x)) // => [1, 7, 11]

If you want to get terse ['1', '7', '11'].map(x => +x)

If I didn't care about rounding I'd just use a primitive constructor

    ['1', '7', '11'].map(Number)

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

#146
post #109

Earlier quoted context omitted.

As a (mostly) outsider, I’ve never understood why JavaScript is so popular in web dev circles. There are so many awesome compile-to-JS languages these days (ClojureScript, PureScript, Elm, ReasonML, Scala.js, etc). What makes people want to use JavaScript instead?

Any time you use anything non-native, you add layers of indirection and potentially lots of impedance mismatch between languages/runtimes. For instance, I know all of the ones you mentioned would be non-starters at my current job because it means we would have to wrap all of our JS libraries/APIs in the language of choice, which is a non-trivial amount of work. Plus, debugging becomes more challenging as you're basic…

I too remember the time when we didn't assume there'd be a Makefile-ish system that has to bundle everything, compile the sass, pull bootstrap, etc. Then there's the map files for debugging that will generate cleanly every now and then.

I've adapted but these strange abstraction languages are still where I'm drawing the line. At a certain point it's like, are you choosing the language for the project or is it the other way around.

Hah, I just remembered Vala.

Edit: Also this thread and the internet in general make me feel bad for liking javascript. It has issues with the global namespace being all wrecked when used for DOM, but the language in and of itself I just find cool for the same reason I find JSON and the way lisp treats objects/data/code cool. So many playa hataz :(

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

#148
post #139

Earlier quoted context omitted.

Did you try testing that? The TypeScript compiler does't say a thing about that code: https://www.typescriptlang.org/play/index.html#src=alert(%5B... TSLint similarly reports nothing even with the tslint:all ruleset: https://palantir.github.io/tslint-playground/?saved=N4Igxg9g... https://palantir.github.io/tslint-playground/

Doesn't seem right, are all the strict compiler options enabled?

Yes, can you post the configuration you used for your original claim?

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

#149

Earlier quoted context omitted.

Because leading 0 implies octal (Base-8). Interestingly, this is also the standard interpretation of IPv4 addresses in that form, where each delimited number [octet] in an IP address that start with a leading 0 should be read as octal. (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.)

(I'm trying to say that this behavior was removed in modern browsers. The only time when modern browsers are allowed to parse strings as a base other than base-10 when the second argument to parseInt is 0 or undefined is when the string starts with 0x or 0X, at which point the browser must parse it as base-16.)

I caught that if it wasn't clear; it wasn't a direct reply but a reply to the whole thread. I was just pointing out why that original behavior existed in the first place and how funny it is that that behavior in the given example is actually more technically correct because IPv4 addresses are supposed to do that.

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

#150

Earlier quoted context omitted.

Both are used. Here you can see Steven D'Aprano, one of the dev of the Python stdlib, naming it "splat": https://mail.python.org/archives/list/python-ideas@python.or... I use "splat" all the time myself. On the other hand, itertools.starmap() is named this way because it does: def starmap(func, iterable): for e in iterable: yield func(*iterable) Things rarely have one name in computing. Hell I call curly brackets "mu…

That’s a mailing list email from 2016, and is a joke about bunch of silly non-standard names for punctuation (e.g. “bang”, “wack”, and “twiddle”). Obviously occasional people are going to pick up terminology from other communities, and the name “splat” has been gaining popularity recently (I had literally never heard that term before a few years ago, and have been writing Python code since 2002). I occasionally hear…

The most famous JS template engine of the early 2000 used to be literally called "mustache" because of it:

https://mustache.github.io/

Post reply on HN