Skip to content
This repository has been archived by the owner on Jan 26, 2022. It is now read-only.

Naming proposal Array.prototype.itemAt() #33

Open
jboler opened this issue Oct 14, 2020 · 24 comments
Open

Naming proposal Array.prototype.itemAt() #33

jboler opened this issue Oct 14, 2020 · 24 comments

Comments

@jboler
Copy link

jboler commented Oct 14, 2020

I'm seeing that .item() is running into compatibility problems. I haven't seen .itemAt() proposed anywhere and it seems to be the most succinct alternative.

@ljharb
Copy link
Member

ljharb commented Oct 14, 2020

.at?

@rkirsling
Copy link
Member

Yeah, based on informal IRC discussion, it seems like a good number of people might support Array.prototype.at over scrapping the proposal entirely at this point.

@0kku
Copy link

0kku commented Oct 30, 2020

Is there a reason .at() is preferred over .get()? I find it frustrating that there seems to be no desire to have consistency in naming between Arrays, Sets, and Maps. Using the name get would also allow a nice parallel with a similar set method to mirror Maps and allow us to have negative indices for setting values as well as getting them.

.item was chosen to align with DOM Collections, but since that name is no longer being pursued due to compatibility issues, I think it's highly undesirable to add to JS's inconsistencies by choosing names that differ from other similar ones. Does get have compatibility issues? Is there a desire to leave the doors open for adding an at method to Maps (or even to Iterables) to get an item by their position?

@tabatkins
Copy link
Collaborator

Yeah, as long as there's no compat issues to fear, I support aligning with Maps and using .get() (and possibly a .set()!)

@jboler
Copy link
Author

jboler commented Oct 30, 2020

I know that EmberJS extends the Array prototype with .get(). I don't know whether it would play nice with a native .get():

https://api.emberjs.com/ember/3.8/classes/Ember.NativeArray/methods/get?anchor=get

@ljharb
Copy link
Member

ljharb commented Oct 30, 2020

get to me suggests it takes an exact key - iow, .get(-1) to me should be [-1], not .item(-1).

@tabatkins
Copy link
Collaborator

For lists, that's not my personal intuition, fwiw.

@ljharb
Copy link
Member

ljharb commented Oct 30, 2020

Noted - also worth pointing out that Set is the analogous List to Array, and Set doesn't have a get - get seems to be more like an operation on maplike things than on listlike things.

@rkirsling
Copy link
Member

rkirsling commented Oct 30, 2020

@ljharb That's because Sets are key-without-value: the only thing get could be is an alias for has.

I do share your concern about get(-1) though, because get makes me feel like we're interacting with the underlying (map-like) Object of the Array.

@bakkot
Copy link

bakkot commented Oct 30, 2020

Conversely, since Sets and Maps are ordered we could reasonably add an at method to those collections which accessed by index rather than by key.

@Jack-Works
Copy link
Member

If we align with Map and Set ("get","set") it might break if someone use "set" in object to determinate if it is a map or set.

@tabatkins
Copy link
Collaborator

also worth pointing out that Set is the analogous List to Array

I can't tell what you mean by this.

@0kku
Copy link

0kku commented Oct 30, 2020

If we align with Map and Set ("get","set") it might break if someone use "set" in object to determinate if it is a map or set.

I feel like adding an analogous at()/get() method on Iterators (like I suggested above) would be far more useful than adding it on Maps, and would make more sense (to me personally, at least). After all, getting an iterator for a Map is reasonably easy, and it would make it useful for other iterable constructs as well. This would also mean that using the same get() name on iterators wouldn't cause a problem as you'd have to access the iterator of the Map explicitly before calling get() on it. However, I have to admit that iterable.get(2) doesn't convey as clearly its meaning of "getting the 2nd item" as iterable.at(2) would.

Either way, I'm strongly in favor of aligning with Map's method naming to avoid repeating the mistake of the completely unnecessary confusion of length/size, has/includes, etc. for similar methods and properties.

Furthermore, something like array.setAt(2, "foo") doesn't read nearly as well as array.set(2, "foo"), and the method for setting being set while the method for getting being at feels unnatural too. If this proposal no longer exists to solve DOM needs, it seems to me like it mainly exists to solve the problem of not being able to use negative indices to count from the end of the array — in which case omitting the ability to set values feels like solving only half of the problem for no apparent reason. Hence, I feel like the naming for a setter method is an important part of this discussion.

@ljharb
Copy link
Member

ljharb commented Oct 30, 2020

@tabatkins i mean, in my mental model, Set and Array are “lists” and Map and Object are “structs” (insert any conceptual term you feel better fits).

@ljharb
Copy link
Member

ljharb commented Oct 30, 2020

@0kku “length” on Map/Set would have made them be considered “arraylikes”, and since they’re not accessible by index, that would have caused much more confusion and bugs. Similarly, arrays are fundamentally different in some ways from Maps and Sets, and consistency in method names isn’t inherently a good thing (nor inherently a bad thing, of course).

@zloirock
Copy link

zloirock commented Nov 17, 2020

I don't know was it already discussed at the current TC39 meeting or not, but my 2 cents:

.at is a perfect name for this method. String.prototype.at already is used in another proposal and this method returns a code point. 7 years ago I proposed allowing negative indexes in this method - but it was rejected. core-js still provide String.prototype.at polyfill for this proposal - and I hadn't any reports that it breaks something.

I think that makes sense to try to use this name and to absorb this proposal - with proposed semantic, but with negative indexes. I hope that no one tried to use negative indexes with core-js implementation, however, it's just a polyfill and a polyfill for a proposal.

@ljharb
Copy link
Member

ljharb commented Nov 17, 2020

@zloirock that core-js has a code point-returning polyfill might actually make that name web incompatible :-/ was it enabled by default in any core-js versions?

@zloirock
Copy link

@ljharb yes, I perfectly understand it. It's in the full (with all proposals) set of polyfills from the first core-js versions. However, I don't think that it's commonly used and most likely no one used it with negative indexes, so - why not use it like in this old proposal, but with negative indexes support - and make all that's we need?

@ljharb
Copy link
Member

ljharb commented Nov 17, 2020

Because with nonnegative indexes, it returns a code unit, not a code point.

@zloirock
Copy link

zloirock commented Nov 17, 2020

But why not to make this proposal work like this:

'a𠮷b'.at(1);  // => '𠮷'
'a𠮷b'.at(-3); // => '𠮷'

? If I understood correctly, it's still a controversial issue.

@ljharb
Copy link
Member

ljharb commented Nov 17, 2020

Consensus was reaffirmed today for the current code point semantics; 'a𠮷b'.at(1) would return 'a𠮷b'[1], and 'a𠮷b'.at(-3) would also return 'a𠮷b'[1], which is not the code point '𠮷'.

@zloirock
Copy link

Ok, in the case of code units semantic, it's really could be a problem.

@Zarel

This comment has been minimized.

@ljharb
Copy link
Member

ljharb commented Nov 18, 2020

@Zarel yes, i made a typo, thanks for correcting me. Fixed.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants