News for hackers. Stuff that matters.
Re:Stage 3 Proposal: Array.prototype.at by ezekg on Wednesday June 02, 2021 @08:35AM (#27367950)
Am I reading this correctly — it's an alias for arr[i] and str[i]? I know languages like Ruby have arr.at(i), but why?
Re:Stage 3 Proposal: Array.prototype.at by antris on Wednesday June 02, 2021 @08:43AM (#27368009)
In addition to negative index support, a function is more easily composable e.g. converting a list of indices to a list of objects: `indices.map(myObjectArr.at)`

I've lost count on how many times I've wrote this function manually.

Re:Stage 3 Proposal: Array.prototype.at by bidirectional on Wednesday June 02, 2021 @09:01AM (#27368188)
> `indices.map(myObjectArr.at)`

That works in this case, but eta-reduction is not generally safe in Javascript due to the variadic nature of many functions, so I wouldn't recommend it in production code. For example `indices.forEach(console.log)` does not work as one would expect.

Re:Stage 3 Proposal: Array.prototype.at by antris on Wednesday June 02, 2021 @09:07AM (#27368235)
Better a function that works in some cases than not having a function at all. Also, by using TypeScript definitions you pretty much always know what's coming in and going out and VS Code will yell at you if you're trying to do something stupid.
Re:Stage 3 Proposal: Array.prototype.at by jakelazaroff on Wednesday June 02, 2021 @09:33AM (#27368481)
That won’t work in this case. TypeScript won’t yell at you if you pass a function that doesn't use all its arguments. If a second number argument is ever added to `at`, your code using it this way will break and TypeScript will not warn you.

This blog post explains why what you’re proposing is dangerous: https://jakearchibald.com/2021/function-callback-risks/#type...

Re:Stage 3 Proposal: Array.prototype.at by antris on Wednesday June 02, 2021 @10:14AM (#27368929)
I guess I'm then somehow doing subconscious mental gymnastics to prevent this, because me and several of my colleagues have coded like this for years and it hasn't been a problem even once.
Re:Stage 3 Proposal: Array.prototype.at by benjaminjackman on Wednesday June 02, 2021 @09:32AM (#27368467)
TypeScript definitions don't block and VS Code does not warn for `indices.forEach(console.log)`

When using eta-reduction in Javascript both functions and all their (optional) arguments have to be known by the programmer and future programmers, instead of needing to know only the argument-slots being used by (x,y,...) => ...

It also defends / insulates against more parameters being added in the future.

Additionally, the way `this` in javascript works (or doesn't for a lot of callbacks) also pushes against using eta-reduction.

Re:Stage 3 Proposal: Array.prototype.at by antris on Wednesday June 02, 2021 @10:19AM (#27368983)
>TypeScript definitions don't block and VS Code does not warn for `indices.forEach(console.log)`

Sure, it's a valid way of logging all the arguments that pass through forEach. I don't see a problem here?

>When using eta-reduction in Javascript both functions and all their (optional) arguments have to be known by the programmer and future programmers, instead of needing to know only the argument-slots being used by (x,y,...) => ...

My VSCode setup shows all arguments of functions automatically. Also, I always avoid optional arguments in my code and writing functions that take in a variable amount of arguments or arguments of different types. I always refactor these out of my codebase.

>Additionally, the way `this` in javascript works (or doesn't for a lot of callbacks) also pushes against using eta-reduction.

`this` is another smell that I always avoid using in my codebase, and refactor code that uses it to work without `this`. I thought `this` being harmful is common knowledge?

Re:Stage 3 Proposal: Array.prototype.at by e1g on Wednesday June 02, 2021 @09:30AM (#27368440)
A function that works in some cases will be a nightmare to debug. The pattern of `indices.map(myObjectArr.at)` is discouraged in JS because it often fails in unexpected ways. For example -

  ["1","2"].map(parseFloat) // works as expected
  ["1","2"].map(parseInt)   // nope
Re:Stage 3 Proposal: Array.prototype.at by antris on Wednesday June 02, 2021 @10:13AM (#27368905)
I've learned ages ago that parseInt cannot be used like this, so it's not a problem for me, but I thought linters already take care of this case? Also I wasn't talking about using parseInt, a broken function like this so I'm not sure what the quirks of old, widely known bad parts of Javascript have to do with using functions as arguments, which is one of the most powerful features of the language.
Re:Stage 3 Proposal: Array.prototype.at by Fatalist_ma on Thursday June 03, 2021 @12:25PM (#27383673)
There's nothing broken about parseInt. The problem is, it can take a second argument(radix), and .map will feed it current item's index as the second argument(and the whole array as the third, but that one will get ignored).

const arr = ['1','2','3']; arr.map(parseInt) is equivalent to: [ parseInt('1', 0, arr), parseInt('2', 1, arr), parseInt('3', 2, arr) ];

Re:Stage 3 Proposal: Array.prototype.at by antris on Friday June 04, 2021 @03:23AM (#27391449)
I know why it works this way. I'm not claiming it has a bugged implementation, I'm saying it's broken by design.
Re:Stage 3 Proposal: Array.prototype.at by inbx0 on Wednesday June 02, 2021 @02:00PM (#27371911)
That will break with

> Uncaught TypeError: Cannot convert undefined or null to object

because `myObjectArr.at` doesn't bind `this` to `myObjectArr`. When the internals of `map` call the `at` function, `this` is just `undefined` instead of the original array and it'll throw.

Luckily Array.prototype.map takes a second argument just for this purpose

    indices.map(myObjectArr.at, myObjectArr)
Re:Stage 3 Proposal: Array.prototype.at by antris on Wednesday June 02, 2021 @02:38PM (#27372329)
Oh wow, I had to try it to make sure. I can't believe how broken the fundamentals of JS are.

There should really be a whole new standard library made from ground up without `this`, mutability and all the other legacy stuff.

Re:Stage 3 Proposal: Array.prototype.at by joppy on Wednesday June 02, 2021 @12:52PM (#27370978)
The alternative being the pretty-much-just-as-short indices.map(i => myObjectArr[i])?
Re:Stage 3 Proposal: Array.prototype.at by antris on Wednesday June 02, 2021 @01:27PM (#27371491)
Composability is not about syntax but being able to express code as values. You can have complex behaviors from pure functions that are guaranteed to work and can be recomposed into more and more complex structures.

It's not a big thing of course with such a simple example, but just try to program without defining a single function and you'll see how tiresome it soon begins to write everything out manually.

Re:Stage 3 Proposal: Array.prototype.at by nvartolomei on Wednesday June 02, 2021 @08:43AM (#27368008)
Proposal hosted on GitHub explains the reasoning behind it https://github.com/tc39/proposal-relative-indexing-method
Re:Stage 3 Proposal: Array.prototype.at by twoodfin on Wednesday June 02, 2021 @08:38AM (#27367974)
A quick read suggests that it adds negative indexing from the end of the array.
Re:Stage 3 Proposal: Array.prototype.at by Pxtl on Wednesday June 02, 2021 @08:45AM (#27368039)
Imho that violates the principle of least astonishment - that "at" would have such different behavior from "[]" for negative numbers.
Re:Stage 3 Proposal: Array.prototype.at by ZephyrBlu on Wednesday June 02, 2021 @08:56AM (#27368132)
That's the whole point of this though... Currently you can't use negative indexes, but this would make them usable.
Re:Stage 3 Proposal: Array.prototype.at by Pxtl on Wednesday June 02, 2021 @04:44PM (#27373797)
Oh, I'd assumed main point was to provide a composable function.
Re:Stage 3 Proposal: Array.prototype.at by pininja on Wednesday June 02, 2021 @08:39AM (#27367980)
Accessing negative indexes currently returns undefined. This adds support for indexing from the end of an array with negative numbers.
Re:Stage 3 Proposal: Array.prototype.at by franciscop on Wednesday June 02, 2021 @08:57AM (#27368143)
This works, but not the way you'd think:

    const arr = [];
    arr[-1] = 'Hello world';
    console.log(arr[-1]);
    // Hello world
Instead of using the negative index, it stringifies the "-1" and uses it as the key of an object both when writing and reading. Thus, arr.length still remains 0
Re:Stage 3 Proposal: Array.prototype.at by maweki on Wednesday June 02, 2021 @08:40AM (#27367981)
It's a function object then.