IMO this is a more fundamental issue with 'map'. A separate indexed map would make sense because you expect functions passed to map to take one parameter in almost all cases and usually when you need indices you should just use a loop.
Some languages use `enumerate` for this. Maps, filters, for loops etc all work on single items, but enumerate wraps them into (index, item) tuples when needed.
I agree with you. I ran into that issue once. Of course I knew map takes a function that it passes value, index, array, I just forgot for a moment. It would arguably be better to have different functions for those.
Very tangentially related, Apple's Metal API has a function that copies a texture. You pass it a width, height, etc... But, if the texture is compressed, then 255 of 256 possible value combos you pass it will be invalid since compressed textures can only be copied in block multiples. I think it would have been a better designed function if it only took width and height in blocks instead of pixels (with uncompressed textures defined has having 1x1 pixel blocks). Then this nonsense of 255 of 256 values being bad would disappear. There's a ton of other inconsistencies in that function. For example, you pass it destinationBytesPerRow when copying to a buffer but if the texture is compressed you pass it say 40 rows and it will only only actually copy 10 rows of blocks and only advance the destination every 4 rows instead of every row. It's arguably a poorly designed function. Thought, I suspect it was inspired by similarly poorly designed functions in other graphics APIs
I can’t speak to Metal, but you’ve gotten at what I wanted to be contrary about in my sibling comment: number (or equivalent, and same goes for other primitives) is an inadequate type. If it’s an array index, it’s not just any number. If it’s a range restricted count of something like pixels, it’s not just any number! Any code in almost any language can box these types so they’re safe to use, but almost no one ever does except in ML langs (or maybe Javaish ones) because across the board it’s a huge bunch of ceremony for mostly worse performance.
I was going to take an even contrarian-er view but after typing it out three times I have to agree, it would be better to just separate them by arity and intent. I frequently use the index parameter, but I never do with a function reference because it’s a footgun from below. And mapping over entries is a well-established pattern, at least enough so that it’s worth the inconvenience of having to do it explicitly.
What is and what should be are separate discussions. But if we want to delve into the topic of what should be, I don’t think adding many different functions for all these cases where this can happen makes sense. It doesn’t scale. The problem, if one believes it’s a problem, is that javascript and typescript are fine with optional and implicit undefined arguments so they never require argument count to line up.
Just use an arrow function to wrap the callbackFn.
We’re talking about one additional function and I don’t think it’s reasonable to extrapolate it to many others. Which is why I started at your position but talked myself out of it trying to make the point.