Clarify the destructuring syntax
On Fri, Apr 11, 2014 at 12:35 PM, Егор Николаев <termi1uc1 at gmail.com> wrote:
- Should the AssignmentExpression of DestructuringAssignment always to be the Object type?
let {length} = "123"; assert(length, 3);
Is this valid?
Yes.
If it is: 2. Should the result of Get(obj, name) always be the Object type if DestructuringAssignmentTarget is an ObjectLiteral or an ArrayLiteral? According the spec 12.14.5.4 step 4.b this expression is invalid:
let {text: {length}} = {text: "123"}; assert(length, 3);
Yes.
You can test this in the web console in a Nightly or Aurora build of Firefox.
Hi Erop,
On Fri, Apr 11, 2014 at 12:35 PM, ???? ???????? <termi1uc1 at gmail.com, mail.mozilla.org/listinfo/es-discuss> wrote:
/ 1. Should the AssignmentExpression of DestructuringAssignment always to be />/ the Object type? />/
javascript />/ let {length} = "123"; />/ assert(length, 3); />/
/>/ Is this valid? />/ / Yes.
No.
13.2.1.4 Runtime Semantics: Evaluation, LexicalBinding : BindingPattern Initializer, step 4
/ />/ If it is: />/ 2. Should the result of Get(obj, name) always be the Object type if />/ DestructuringAssignmentTarget is an ObjectLiteral or an ArrayLiteral? />/ According the spec 12.14.5.4 step 4.b this expression is invalid: />/
javascript />/ let {text: {length}} = {text: "123"}; />/ assert(length, 3); />/
/>/ / Yes.
No.
13.2.3.7 Runtime Semantics: KeyedBindingInitialization BindingElement : BindingPattern Initializer_opt, step 4
people.mozilla.org/~jorendorff/es6-draft.html#sec-runtime-semantics-keyedbindinginitialization
You can test this in the web console in a Nightly or Aurora build of Firefox.
You can test this in traceur or my test implementation [anba/es6draft]. ;-)
Maybe the final draft will revert this restriction, it was originally
introduced in rev17. It is somewhat annoying, especially for the string
type, because the restriction also applies to spread array elements and
spread calls. For example [..."abc"]
must now be written as [...new String("abc")]
to get the array of code points.
- André
@Till Schneidereit. Sorry, but I am misunderstand you. Are you saying that this:
let {text: {length}} = {text: "123"};
is valid?
I am testing this behavior in traceur and FireFox. traceur says me that this is invalid spec says me that this is invalid FireFox 30.0a2 says to me that this is fine and quite logical.
When in doubt, listen to André when it comes to spec details. So yes, it's valid in Firefox, but invalid per spec. Also, I agree that Firefox's behavior makes more sense, so I hope this'll change.
@André Bargull Are there any reasons for these restrictions? It confuses me. If I can for-of over string, so why can't I destructuring it?
On 4/11/2014 2:02 PM, Егор Николаев wrote:
@André Bargull Are there any reasons for these restrictions? It confuses me. If I can for-of over string, so why can't I destructuring it?
I'd say it's mostly a language designer decision and it may still change before the final specification is published. I'd encourage you to file bug reports at bugs.ecmascript.org and/or post to this mailing list if you find any issues with the current specification draft. That way Allen (the spec editor, cc-ed) and other TC-39 members are notified and can take appropriate actions.
- André
On Apr 11, 2014, at 5:22 AM, André Bargull wrote:
On 4/11/2014 2:02 PM, Егор Николаев wrote:
@André Bargull Are there any reasons for these restrictions? It confuses me. If I can for-of over string, so why can't I destructuring it?
I'd say it's mostly a language designer decision and it may still change before the final specification is published. I'd encourage you to file bug reports at bugs.ecmascript.org and/or post to this mailing list if you find any issues with the current specification draft. That way Allen (the spec editor, cc-ed) and other TC-39 members are notified and can take appropriate actions.
This was discusses fairly extensively in TC39 meetings and on this list. The final consensus was that non objects should not be destructurable (ie, ToObject is not applied). One argument against allowing non-objects is that it might be future-hostile to anticipated future proposal to turn destructuring into more general pattern patching,
This is the decision that is reflected in the ES6 draft starting with rev17. As it stand right now, there is no advocacy within TC39 for reopening this decision.
On the one hand, the is a bug in current spec that allows the
let {length} = "qwe";
but disallow
let {text: {length}} = {text: "qwe"};
On the other hand, this restriction can lead to hard-reproducibly errors. When I write a function such as:
function returnLength( {length} ) {
return length;
}
I can't be sure that foreign user will not use it as:
var obj = { toString(){ return "test" } };
returnLength( obj + "" );
In this case, I have no other chose, but to rewrite function without destructuring in function parameter:
function returnLength( text ) {
text = new String(text);// do not remove it, without this line following
destructuring pattern will throw a error
let {length} = text;
return length;
}
Of course, in real app this function would be more complex.
On Apr 11, 2014, at 8:56 AM, Егор Николаев wrote:
On the one hand, the is a bug in current spec that allows the
let {length} = "qwe";
Where in the spec. the bug? Is a ticket filed for it? Indeed, this is supposed to be an error.
The ticket ecmascript#2639
After firing a bug I read the spec again and realised that Get (O, P) should already throw a Error. So maybe I am misunderstood this from the beginning. In this case section "12.14.5.4 4.b. If Type(v) is not Object, then throw a TypeError exception." is useless because it already has a type checking in Get function.
On Apr 11, 2014, at 10:29 AM, Егор Николаев wrote:
After firing a bug I read the spec again and realised that Get (O, P) should already throw a Error. So maybe I am misunderstood this from the beginning. In this case section "12.14.5.4 4.b. If Type(v) is not Object, then throw a TypeError exception." is useless because it already has a type checking in Get function.
The top level assignment check is done in 12.14.4 step 6
let {length} = "123"; assert(length, 3);
Is this valid?
If it is: 2. Should the result of Get(obj, name) always be the Object type if DestructuringAssignmentTarget is an ObjectLiteral or an ArrayLiteral? According the spec 12.14.5.4 step 4.b this expression is invalid:
let {text: {length}} = {text: "123"}; assert(length, 3);