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

Should we forbid array patterns for rest-properties? #43

Open
anba opened this issue Apr 25, 2017 · 15 comments
Open

Should we forbid array patterns for rest-properties? #43

anba opened this issue Apr 25, 2017 · 15 comments

Comments

@anba
Copy link

anba commented Apr 25, 2017

It's not really useful to support var {...[]} = {} since Object.prototype doesn't have a Symbol.iterator property. Maybe we should simply forbid array patterns in this position?

@ljharb
Copy link
Member

ljharb commented May 12, 2017

The RHS could be something with a Symbol.iterator property, however, and Object.prototype[Symbol.iterator] might be set.

@saambarati
Copy link

@ljharb This feels like a weak argument in favor of this.

I don't see how the rhs having Symbol.iterator would make any difference. I think the only use case would be setting Object.prototype[Symbol.iterator] to something. I don't think this is a real use case. It's really unintuitive and not what users expect. There would be nothing stopping us from adding it in the future if we found a real use case. It seems unwise to add it without a real one though.

I also think we should forbid further object destructuring, e.g:
let {...{a}} = expr because why would you not just write this as:
let {a} = expr

(I also brought this up on the main tc39 issues: tc39/ecma262#915)

@ljharb
Copy link
Member

ljharb commented May 12, 2017

Oh right, actually for object rest/spread, Symbol.iterator doesn't apply at all - it uses Object.assign semantics.

@ljharb
Copy link
Member

ljharb commented May 12, 2017

(Setting things on Object.prototype, or any other prototype object, is a "real use case"; but it's moot because Symbol.iterator is irrelevant to this proposal)

@saambarati
Copy link

The semantics for something like this only effect an Object.prototype[Symbol.iterator] or something where Symbol.iterator ends up as part of the rest properties (if this is even allowed)
E.g
let {...[x]} = expr
Is like doing:
let {...tmp} = expr; let [x] = tmp;
Where tmp is an object with Object.prototype as its proto. This ends up performing the iterator protocol on tmp.

@ljharb
Copy link
Member

ljharb commented May 12, 2017

Gotcha. That does seem weird.

@littledan
Copy link
Member

Cc @gsathya @caiolima

@caiolima
Copy link

I agree that it seems weird as well. IMHO it makes sense syntactically, however I can't see a good use case that seems worth keeping it in the current proposal version.

@caiolima
Copy link

I also think we should forbid further object destructuring, e.g:
let {...{a}} = expr because why would you not just write this as:
let {a} = expr

Just clarifying, I agree with array related topic, however I'm not in favor to allow just identifiers into rest destructuring.

@ajklein
Copy link

ajklein commented Jun 12, 2017

The conclusion in https://github.com/tc39/tc39-notes/blob/master/es8/2017-05/may-23.md#conclusionresolution-10 says that the consensus is to disallow both ...[ and ...{, but I don't recall what the motivation for disallowing ...{ was (nor are the notes helpful, as they point out that it does have non-erroring semantics). Does anyone else? I see @saambarati arguing for this above, but I don't think "you could just write it another way" should be a sufficient argument (since destructuring is all syntactic sugar anyway, you could just write out the destructuring by hand).

I'd prefer to avoid disallowing ...{ as part of resolving this issue, since it seems unnecessary to disallow, and introduces non-uniformity with array rest patterns. That is, [...{}] is valid, but {...{}} is invalid. The same uniformity argument exists with {...[]}, but in that case the counter-argument is that it will always result in a TypeError.

littledan added a commit to littledan/proposal-object-rest-spread that referenced this issue Jun 15, 2017
This was the consensus recorded in the minutes for the May 2017 TC39
meeting, following bug tc39#43
@saambarati
Copy link

@ajklein I think [...{}] is fundamentally different than {...{}} because in the first one, you might want to grab named properties from the resulting array, like: [...{length}].

I think the symmetry argument would be that we already allow: [...[]], so we should allow {...{}}. That said, I'd argue allowing that we probably should've disallowed [...[...]] since it's redundant.

@ajklein
Copy link

ajklein commented Jun 15, 2017

@saambarati It sounds like you're thinking of this from the perspective of a user wanting to accomplish some specific task (which is a totally reasonable way of thinking about things, I should say!), rather than from the direction of what each bit of syntax does, semantically. In the latter sense, the {} in [...{}] and {...{}} are identical (and have the same meaning as {} anywhere else), which was what I was trying to get at.

@saambarati
Copy link

@ajklein I see what you're saying, and agree. The way I've been thinking about it is like: the context of where the ... is determines how we spread (e.g, is it in a destructuring array or object). What comes after the ... tells us how to bind to the temporary thing that's been spread. I've been thinking about these two operations when combined together, not individually.

Anyways, I'm not sure if we've made progress on deciding what to do here. I wasn't at the meeting, so I'm not sure exactly what was discussed. I find the argument of not allowing users of the language to introduce, except in the case of Proxy, unnecessary redundancy more compelling than doing something just so there is symmetry in the syntax.

@sebmarkbage
Copy link
Collaborator

The argument (by Allen) that convinced me that we needed to address this at all (rather than just leaving it as a runtime error) was that this syntax might make sense for one of the additions we'll want to make in the future.

For example, if we add a custom key iteration protocol (similar to Symbol.iterator) that allows objects to implement their own custom key iteration mechanism. Then the {...[]} syntax might make sense for extracting key names or something to that effect.

What that means for {...{}} in that scenario, I don't know. It seems like an overly convoluted feature to use this syntax for. However, it seems plausible enough that there is a design that fits into this space where you'd want to have {...{}} and {...[]} line up with the new design.

Since {...{}} is fairly useless, albeit not completely useless (allows destructuring only own properties), it seems to me that it would be better to error on the side of reserving this design space.

@ajklein
Copy link

ajklein commented Jun 15, 2017

@sebmarkbage thanks for the background and motivation. I do think it would be weird for {...{}} to do anything different, but given its uselessness I can't argue super-strongly to keep it around.

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

7 participants