"indexOf" should be "firstIndexOf"

I respectfully disagree ... arrays have been looped 0 to length forever in pretty much every PL so having that as default feels like the most natural expectation to me.

On top of that, indexOf(value, start_index = 0) is the real signature, firstIndexOf(value, start_index = 0) would mislead within the name itself to me, just confusing, it adds nothing.

That being said, if you believe any of this is really worth anyone time, the approach usually is "publish your npm package that adds these methods to the Array.prototype and verify how much interest there is behind" ... polluting globals is discouraged, usually, but here and there many do that so you have a chance to measure the impact of your idea. If within 6 months nobody uses your module except you, maybe you have your answer ... if everyone wants it, maybe we have your attention?

edit as metaphore, if needed "alphabetically ordered" meets people expectations when it's A to Z, never the other way around ... I don't think we want people to ask for "alphabetically ordered ascending order" to mean the default order everyone expects, if that makes sense.

Not usually, always - and you don't need to pollute globals to demonstrate demand.

If we're going to argue what the philosophically correct name is and not just what is and isn't practical, the author of the post is completely correct that the correct name for the method is firstIndexOf.

Yes, I agree that most programmers reflexively understand indexOf to implicitly mean `"first index of".

My simple rule is: the difference between names must be the same difference as the difference between implementations.

This rule is satisfied by the choice of names firstIndexOf and lastIndexOf as the difference between first and last is indeed exactly the difference between the implementations.

What's implicitly suggested by the difference between indexOf and lastIndexOf is that one of these functions can definitively say which index is the index and the other is choosing the last of many options. But we know that isn't true! We know we're doing the substitution in our head from "the [only] index of" to "the first of many options". Your being so natural at doing this substitution that you don't even notice it happening renders it no less relevant.

But idunno, why argue the actual semantics anymore. I'm told that programming has died, so certainly getting things right is no longer a concern.

Once again this triggers the missing stair paradox. If you've gone through hazing, you tend to feel that everyone else should have to go through the same hazing.

This is kind of a little hazing. Once you've been through it, you don't see anything wrong with it. Seeing what's wrong with it would require the naivete of a true beginner, and true beginners are one class of people who don't forcefully advocate for their needs on the TC39 forums. This is the paradox: the missing stair doesn't get fixed because the people who could fix it are already too used to jumping over it.

fwiw, I don't dispute that, knowing lastIndexOf was coming, it should have been named firstIndexOf - but string indexOf was added in 1995, string lastIndexOf in 1997, and both array methods added in 2009. While it probably would have been web compatible in the early 2000s to change it, it's decidedly not so now, and the committee has repeatedly declined to add aliases solely because the name is clearer.

Yeah and I don't really blame them for that.

Well, that's not entirely true. I wouldn't blame them if the committee was clearly interested in protecting the protocol-ish-ness of Javascript, but by and large I haven't seen that it is.

In class-based code architecture something is protocol-ish if it can easily be wrapped or facaded without being extended (or proxied). It is a class that will not, even in the future, gain new members, and this is precisely what makes it possible to treat as a kind of duck-typed contract.

The committee's actions as I have observed them have not protected this quality. Maps, at their inception, were extremely protocol-ish. You could easily make a variety of Maps that were protocol compliant even if they weren't actually instanceof Map. But then the committee, seeing no value in this, started slapping random high-level functionality into there, just like they did with Arrays. Arrrrrrrrgh

Iterators. Very protocol-ish. So slap a bunch of instanced helper methods on them! Arrrrrrrrgh!!

Now the protocol that had a surface area of one method has a surface area of 20 methods. Leave any of them off? You're not an iterator! You can't be used like an iterator!!!!!!

And worse than that, you can't just implement the 20 methods and be done with it, because next year there will be 25 and the year after that there will be 30.

You have to implement them because this is a protocol and in a protocol you produce values for a consumer you don't own. You have to be liberal in what inputs you accept, so better do all 30 methods to be safe.

So yeah if the committee wasn't so determined to absolutely trash this aspect of value-creation in the language, I would certainly agree with you beyond all doubt.

As it is? If we're embodying the spirit of decisions made so far, just throw the damn alias on there.

Here's my challenge. If you are going to block throwing this alias on, tell me how the committee will defend protocol-ish modes of interoperability -- which is, to be again very explicit, duck-typed interoperation not based on class extension or instanceof.

I'm not sure what you mean; you can still do that. The new Set methods, for example, while requiring their receiver to be proper Sets, accept any Setlike as arguments, quite intentionally.

What about iterators?

If the iterator helpers were static methods there would be no issue: the iterator contract would still just be one method: next (...and maybe return/throw -- the waters were already a little muddy).

Making the iterator helpers instance methods, though, that made them a de-facto part of the contract, no? You're the one saying JS is all about what's reachable and, well, all those methods are reachable through the protocol.

It's almost like a little self-inflicted Embrace Extend Extinguish play against the iterator protocol.

First embrace:

  • the Iterator class will implement the iterator protocol, which so far means a next method.

Then extend:

  • 95% of the time you'll be using our proprietary platform, so here are some great features like iter.map() and iter.filter() that you can use when you are interoperating with other users of the proprietary Iterator platform. These proprietary helpers are super helpful, amiright?

Then extinguish:

  • Something important broke because you didn't use the proprietary iterators and our code assumed it could do iter.map(). Henceforth it is decreed that all iterators shall be Iterators.

Now the original protocol remains on the books, but in practice the new protocol has superceded it. Whatever the exact adoption ratio, it remains that the ecosystem is split between two protocols, where once there was just one.

polyfills require that but yeah, you shouldn't need, but array literals are hard to beat (just like object literals) in terms of ergonomics ... if the library is honest around being a "discussed / proposal" I don't see particular harm (also because I won't use that module anyway). The for/in shenanigans times are a thing from the past, imho.