News for hackers. Stuff that matters.
Re:FP techniques that will help you write better JavaScript by fulafel on Friday February 11, 2022 @11:51AM (#30303631)
map() is great in most languages but JS manages to WTF it:

  > ['1', '2', '3'].map(parseInt)
  [1, NaN, NaN]

  > ['3', '2', '1'].map(parseInt)
  [3, NaN, 1]
Re:FP techniques that will help you write better JavaScript by hoblaypop on Friday February 11, 2022 @11:58AM (#30303735)
From https://stackoverflow.com/questions/22036300/what-is-1-2-3-m...

// Consider: ["1", "2", "3"].map(parseInt); // While one could expect [1, 2, 3] // The actual result is [1, NaN, NaN]

// parseInt is often used with one argument, but takes two. The second being the radix // To the callback function, Array.prototype.map passes 3 arguments: // the element, the index, the array // The third argument is ignored by parseInt, but not the second one, // hence the possible confusion. See the blog post for more details

function returnInt(element){ return parseInt(element,10); }

["1", "2", "3"].map(returnInt); // Actual result is an array of numbers (as expected)

Re:FP techniques that will help you write better JavaScript by brundolf on Friday February 11, 2022 @11:55AM (#30303686)
This problem isn’t about map(). parseInt takes a second argument - a radix - and map passes a second argument to to the callback: an index

The normal solution is to write an inline function; “shortcutting” it by just passing a named function directly can be nice when it’s appropriate, but it often isn’t what you want to do

Re:FP techniques that will help you write better JavaScript by dragonwriter on Friday February 11, 2022 @02:37PM (#30306031)
> This problem isn’t about map().

Yes, it is.

Its about .map(), and the broader design of the API around it. Yes, map passes extra args and parseInt takes optional args, and it wouldn’t be a problem if both of those weren’t true. It would be better if .map() was one-arg and had friends .map_with_index(), .map_with_collection(), map_with_index_and_collection().

(It would be better if .map() wasn’t an Array-specific method but part of a general collection protocol that returned [and was applicable to] generators instead of returning Arrays, and then you also had companion methods to like .enumerate(), but that’s…well, farther afield.)

> The normal solution is to write an inline function

Yes, that’s the solution, but that doesn’t say that the design of .map() isn’t a critical component of there being something to solve in the first place.

Re:FP techniques that will help you write better JavaScript by throwawa923423 on Friday February 11, 2022 @06:37PM (#30308342)
I think it is important that you brought awareness to this, this is a really good point and I agree 100%. JavaScript does have hygiene issues with its API design.
Re:FP techniques that will help you write better JavaScript by fulafel on Friday February 11, 2022 @12:06PM (#30303857)
Coming from outside the JS world, the problem is exactly about surprising behaviour of map - the function that's probably the oldest and best estabilished element of FP vocabulary. The extra index argument is not present in functions called "map" in other languages.

Also, the silently ignored argument count mismatch errors heavily contribute to the problem. You may have used other functions with map() and never knew it's always passing an extra argument in, because JS silently ignores this error.

Re:FP techniques that will help you write better JavaScript by brundolf on Friday February 11, 2022 @12:11PM (#30303937)
Sorry if it’s unfamiliar, but the index argument is critical to many real use-cases.

As far as ignoring errors silently, sure, but I’m not even sure what the error would be in this case. Index is a number and radix is a number; even typescript won’t complain about this because the types line up.

Re:FP techniques that will help you write better JavaScript by fulafel on Saturday February 12, 2022 @04:49AM (#30311455)
I ran across this anecdote about how people don't know (or acknowledge?) the existence of the index argument of Array.map. This is a link to the manuscript of the well regarded book on JS FP techniques "Javascript Allonge". The book was linked elsewhere in these comments. The index arg is not mentioned!

https://github.com/raganwald/javascript-allonge/blob/db7c435...

Re:FP techniques that will help you write better JavaScript by dragonwriter on Friday February 11, 2022 @02:44PM (#30306111)
> Sorry if it’s unfamiliar, but the index argument is critical to many real use-cases.

Only because .map() is an Array method, not a method of a generic iteration protocol applicable to other iterables (including generators.)

In Python, while map is a built-in function instead of a method, and you’ll probably want a comprehension instead, if you want the index for a map (or in a comprehension), you just wrap call enumerate() and go from an iterable of items to an iterable of pairs of (item, index), so:

  map(f, enumerate(collection))
In Ruby, if you want the index in a map, you just do:

   collection.each_with_index.map {|item, index| … }
Re:FP techniques that will help you write better JavaScript by fulafel on Friday February 11, 2022 @12:13PM (#30303959)
Is it critical in some way that's absent from all the other langugaes that have a map()? There are standard, composable, explicit patterns in Python, Clojure, and I presume other map()-equipped anguages to get you the indices along with the items. (enumerate in Python and map-indexed in Clojure)

The error I was talking about was the argument count mismatch erorr, that would have taught you on all the other times you used map() without knowing about the extra index argument.

Re:FP techniques that will help you write better JavaScript by dragonwriter on Friday February 11, 2022 @02:47PM (#30306165)
> Is it critical in some way that’s absent from all the other langugaes that have a map()?

Yes, but only because of other non-ergonomic design decisions of the API its part of (particuarly, that it is an eager API attached to the Array class returning Arrays; if it were a lazy API of generalized iterable protocol that returned and could be used on generators, then you could just also have an “enumerate” and “with_collection” companion methods, but as it is, even if you made standalone functions for those purposes, for the output to be used with .map() you need them to return Arrays, which means you are accumulating bulky intermediate results.)

Re:FP techniques that will help you write better JavaScript by fulafel on Friday February 11, 2022 @03:21PM (#30306531)
Yes, eagerness would use additional space in the case of a Python enumerate() style solution. This would be acceptable in my view and aligned with the general JS design. But an alternative is the map-indexed style solution (aka the current Array.map with a different name).