00:03
<voidhedron>
if mutation is desired to be avoided, toEmpty() could be used, but then its essentially = [] and falls under the same issues as it, so it becomes worthless
00:07
<bakkot>
Symmetry with other languages is generally something I'm in favor of when designing new features but is not in itself adequate reason to add a new feature when there is already a fine way of accomplishing the same thing.
00:49
<voidhedron>
tbh I don't understand the reasoning against adding methods to Array.prototype, or rather I couldn't even find one
00:49
<voidhedron>
what was linked were statements of Mozilla's (and them only) stance against them, with no actual backstory on the reasoning
00:54
<bakkot>
the reason was that adding methods with reasonable names breaks websites
00:54
<bakkot>
e.g. we tried to add groupBy and that broke stuff, and then we tried group instead and that broke other stuff
00:54
<bakkot>
and the breakage is often quite subtle
00:55
<bakkot>
this is a bad experience for everyone and Mozilla would like to avoid repeating that experience
00:57
<shu>
Chrome agrees with Mozilla on this btw
01:03
<voidhedron>
how does it breaks websites to add properties that never existed before?
01:06
<shu>
many ways, one particular frustrating way was that there were uses of Array instances as hash maps, and group was being used as a key
01:06
<Kris Kowal>
libraries that monkey-patched prototypes with the same method name break if you replace them with a function that does something different
01:07
<Kris Kowal>
some of these are interesting
01:07
<Kris Kowal>
for example, that one time I monkey patched Array.prototype.clear such that .clear called .splice such that registered change observers would fire
01:08
<Kris Kowal>
pretty sure that code is in WRT modems now
01:09
<bakkot>
function getGroupFromThing(x) {
  return x.group || x;
}

let things = [
  {
    group: [42],
  },
  [42],
  [44, 45],
  {
    group: [46],
  }
];

console.log(things.map(getGroupFromThing)); // good, all arrays

Array.prototype.group = function(){/*...*/};
console.log(things.map(getGroupFromThing)); // oh no :(

01:13
<voidhedron>
but people monkeypatch all sorts of things in all sorts of JS builtins, not just Array
01:14
<voidhedron>
if we start catering to those where does it stop? are we just going to forget the idea of adding new methods to anything ever?
01:15
<voidhedron>
what about top level variables? are we going to also stop considering adding new builtins entirely some random person could have a top level variable with the same name?
01:17
<bakkot>
https://developer.chrome.com/blog/smooshgate/#why-dont-we-just-keep-the-existing-name-and-break-the-web
01:17
<voidhedron>
it seems to me like a terrible and extremely disruptive to the language's progress decision to care for behavior in clear violation of the standard, every monkeypatcher is (or should) be aware that their code is invading a place it should not and it has no safety guarantee to itself
01:17
<bakkot>
this conversation has been had at length; I'm happy to link you to resources but we're not going to rehash it
01:17
<bakkot>
also the code I wrote does not do any monkeypatching
01:17
<bakkot>
if you read it
01:18
<bakkot>
(not that this really makes a difference to anything)
01:28
<voidhedron>
I've read the SmooshGate link, interesting history that I didn't know happened, but it doesn't really answer my question at all, where is the line drawn between caring or not about monkeypatches for a specific name for some new feature? How is anything able to be added if we constantly worry about this?
01:29
<bakkot>
if we think the risk is low enough we try it and see
01:29
<voidhedron>
For instance what differs flatten or group from at or toSorted
01:29
<bakkot>
Mozilla no longer considers the risk to be low enough for new array prototype methods with reasonable names
01:30
<voidhedron>
how is that risk factor measured exactly?
01:31
<bakkot>
we just sort of guess
01:31
<bakkot>
I mean, what happened with flatten is that we tried, and it broke stuff
01:31
<bakkot>
that is to say, browsers shipped it, that broke a bunch of websites, so they unshipped it
01:31
<bakkot>
this did not happen for toSorted
01:31
<bakkot>
but whenever this happens it is very bad, even though we can in principle unship and find a new name
01:32
<bakkot>
this happened multiple times for group and Mozilla is not willing to pay that cost for future methods unless we think the risk is very very low
01:32
<bakkot>
which there is no practical way to objectively measure without shipping and seeing what breaks, and shipping is the thing they want to avoid, so we're just going to have to guess
01:39
<voidhedron>
so just trial and error, I see, I also found out at actually apparently went through the same kind of problem being originally to be called item, ironically I'm actually a little glad about that one, at is much nicer πŸ˜‚
02:47
<ljharb>

So to condense the point, in my view there are a few arguments for adding Array.prototype.clear() as stdlib sugar for .length = 0:

  1. The base case for it is just that it would be the "one obvious way" of performing a common operation – emptying an array. Obvious in terms of the developer experience as well as performance, which is not quite the case for any of the solutions JS developers have today (and usually have to learn from StackOverflow):
    • = [] for one requires usage of var/let; not in-place, which can be seen at a glance, so immediately not ideal performance-wise
    • .length = 0 is just not the way this works in any mainstream other language, this trips developers up
    • .splice(0) works quite sensibly, but the semantics of splicing are a bit different, so this again isn't the obvious way of doing this
  2. Coming from most other mainstream languages (e.g. Java, C#, C++, Python, Rust, Kotlin), you just use .clear() to empty an array (aka vector/list). The convention is basic to the core.
  3. In terms of the cost of adding Array methods, JS has come a long way since ES2015 and the new annual release process. There's really good precedent:
    • Array.prototype.find() in ES2015 (just sugar over a for loop),
    • Array.prototype.includes() in ES2016 (sugar over .indexOf(), which itself is sugar over a for loop)
    • or this year: Array.prototype.toSorted() (sugar over .slice().sort(), again all coming down to iteration).
      All really good quality-of-life improvements, and rather comparable to Array.prototype.clear() both in terms of implementation complexity (low on the scale) and utility (fulfilling a specific but universal use case)
I’m skeptical it’s actually all that common.
09:36
<matlokam>
Is there a good way to verify that the web won't break that'd be a step short of shipping an implementation in browser stable channels? Well, MooTools for one does not set Array.prototype.clear, so that's a relief. I remember that affair, but I'm not familiar with group woes. I'm curious, what was the pain there?
09:39
<annevk>
You could do some research with HTTPArchive data and maybe GitHub (and that might make your case stronger if you did it well), but generally actually shipping is the real test.
15:36
<bakkot>
HTTPArchive wouldn't've caught the group ones
15:37
<bakkot>
regressions included https://bugzilla.mozilla.org/show_bug.cgi?id=1791415 https://bugzilla.mozilla.org/show_bug.cgi?id=1799522 https://github.com/webcompat/web-bugs/issues/112552
15:38
<bakkot>
So, no, there is not any way to verify the web won't break short of shipping
16:10
<annevk>
It wouldn't have caught those regressions, but maybe there were more. It's been quite a useful tool for evolving HTML.
16:15
<bakkot>
Yeah, it can confirm presence but not absence of issues
16:39
<Michael Ficarra>

ECMAScript 2023, the 14th edition, introduced the toSorted, toReversed, with, findLast, and findLastIndex methods on Array.prototype and TypedArray.prototype, as well as the toSpliced method on Array.prototype

16:39
<Michael Ficarra>
sounds like adding methods to Array.prototype actually works out more often than it doesn't πŸ€”
16:45
<nicolo-ribaudo>
Probably multi-word methods are safer
16:45
<nicolo-ribaudo>
And with is a bad keyword so probably people were scared of using it :P
16:47
<bakkot>
also "this only causes us a huge amount of pain a third of the time we try it" isn't that compelling really
16:50
<ljharb>
it's way less than a third. but it's such a huge amount of pain that mozilla and google's position here is understandable.
16:57
<bakkot>
flatten, item, groupBy, and group all had in-the-wild webcompat issues. by my count we've attempted to add a total of 14 methods to Array.prototype since 2015 (flatten, item, groupBy, group, flat, flatMap, at, toSorted, toReversed, toSpliced, with, findLast, findLastIndex, includes). so it's pretty close to a third.
16:58
<bakkot>
and includes was renamed from contains after it was found to break mootools IIRC
16:59
<bakkot>
at also had in-the-wild issues, come to think, we just managed to paper over them
17:00
<bakkot>
yeah contains was also an in-the-wild breakage, just that it was prior to 2015 https://bugzilla.mozilla.org/show_bug.cgi?id=1075059
17:16
<Chris de Almeida>
Array.prototype.jettison(all)
17:16
<Andreu Botella>
Array.prototype.engroupen
17:19
<ptomato>
isn't grouping just a special case of smooshing, if you think about it
17:25
<ljharb>
fair enough on the stats