Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make tuples usable as "entry" objects #107

Closed
bakkot opened this issue Apr 3, 2020 · 12 comments · Fixed by #264
Closed

Make tuples usable as "entry" objects #107

bakkot opened this issue Apr 3, 2020 · 12 comments · Fixed by #264

Comments

@bakkot
Copy link
Contributor

bakkot commented Apr 3, 2020

Object.fromEntries and the Map constructor enforce, via AddEntriesFromIterable step 4.d, that the "entry" objects returned by the iterable they take is of Type Object so that you cannot do, for example, Object.fromEntries(["ab"]) and get { a: "b" }.

I think it makes sense to allow passing a tuple there as well, so that you could do Object.fromEntries([ #["a", "b"] ]) and get { a: "b" }.

See also #102, which is the other half of this.

(This isn't something which really requires worrying about at this stage, I just didn't want to forget.)

@rickbutton
Copy link
Member

100% agree

@ljharb
Copy link
Member

ljharb commented Apr 3, 2020

I agree; everywhere that currently accepts an entry that must be an Object should also accept a Record (with 0 and 1 keys) or a Tuple of length >= 2.

@rricard
Copy link
Member

rricard commented Apr 9, 2020

I think it's worth attaching this to this proposal. We can put in the proposal text a simple statement saying that both records and tuples should behave as their equivalent objects and arrays in built-in functions. Then we'll keep that in mind writing the spec, we can add to the algorithms as we go.

@Jack-Works
Copy link
Member

We can put in the proposal text a simple statement saying that both records and tuples should behave as their equivalent objects and arrays in built-in functions.

And only when we won't modify them (Object.assign)?

@rricard
Copy link
Member

rricard commented Apr 9, 2020

Yes! Or consider it a no-op but I'd prefer to throw.

@littledan
Copy link
Member

I'm wondering whether it'd be better for that algorithm to use RequireObjectCoercible rather than check the type. That would permit this interaction without special-casing.

@ljharb
Copy link
Member

ljharb commented Apr 15, 2020

That would be very weird, because there'd only be 3 primitives for which a Get of 0 and 1 could possibly/practically give you a meaningful value, and 2 of them are this proposal. I think making sure it's an Object or a Record or a Tuple (perhaps checking that with a new abstract operation) makes more sense.

@littledan
Copy link
Member

@ljharb I'm OK with checking if it's an Object or Record or Tuple if others prefer it, but I have trouble understanding this argument. It's not a meaningful use case, but you could define Number.prototype[0]. But, more broadly, I think our general practice in the JS spec is to use RequireObjectCoercible, not checking if something is an Object, as the guard before doing a property access. For example, this is what Object.fromEntries does on the iterable itself before trying to iterate over it, which is why we don't need to make any changes to allow a Tuple as the outer container (even though I'm not recommending to JS programmers to take advantage of it by defining Number.prototype[Symbol.iterator]!).

@littledan
Copy link
Member

BTW sorry for missing this in earlier review. The reason I'm interested in getting this right is that I want to really understand how many special cases we need to make for Records and Tuples. My expectation was that we wouldn't need to have many, due to patterns like using RequireObjectCoercible/Get that would "just work" and compose with other mechanisms that Records and Tuples have.

@ljharb
Copy link
Member

ljharb commented Apr 17, 2020

Right, but the convention in all entries places (that fromEntries followed) is to ensure it's an Object, I assume to catch bugs (which a non-object will be highly likely to be).

@littledan
Copy link
Member

Skimming through the spec, there are tons of places where we check that type type of something is not Object; this location is far from unique. To take a random example, ToPropertyDescriptor. I can accept that the error catching properties are useful.

I think part of this proposal would necessarily be establishing a new convention across the spec for where Records and Tuples are acceptable, and applying it uniformly. I'd suggest that, in all locations which require Objects, we also accept Records and Tuples, unless there is a specific reason to reject them. However, this doesn't imply that we'd suddenly accept other primitives; we'd leave their rejection in place as is.

What do other people think of this policy? Would it be too liberal?

@ljharb
Copy link
Member

ljharb commented Apr 24, 2020

It'd be ideal to enumerate all the cases, to be sure any specific reasons have been identified, but that plan seems good to me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
6 participants