An array destructing specification choice
Axel Rauschmayer
axel at rauschma.de
Sun Nov 6 10:01:35 PST 2011
>> One more thought: Should the following assignments produce the same result?
>>
>> [x, y, z] = {length:2, 0:0, 1:1, 2:2}
>> [x, y, z] = [].slice.call({length:2, 0:0, 1:1, 2:2})
>
> did you intend to use the same "length" value in both of the above lives?
Yes, corrected above.
>> Then the decision boils down to whether an array conversion happens (however implicitly) on the rhs or whether the lhs is syntactic sugar for
>> x = rhs[0], y = rhs[1], z = rhs[2]
>
> As I've mentioned in a reply to another message. There are currently no "array conversions" in ES. Instead, Array operations/functions are always defined to in a manner that applies to all objects, not just instances of the Array constructor.
I would argue that [].slice.call(value) is the de-facto way of converting a value (such as arguments) to an array.
> Here is another example of why desugaring to [ ] is to simplistic a view of destructuring:
>
> let [a=0, b=1] = [,"one"];
>
> Note the default value initializers to the right of the declared identifiers. Such initializers provide the value when the RHS of the initializer for the entire destructuring pattern does not.
>
> What is the value of the variable 'a' after this statement? Is it undefined or is it 0?
>
> If destructuring initialization is a simple desugaring to [ ] access then the above means the same as:
>
> let _rhs = [,"one"];
> let a=_rhs[0], b=_rhs[1];
>
> and the value of 'a' will be undefined.
>
> Note that there was no reason to include the =0 or =1 default initializers anywhere because _rhs[X] yields a value for all possible values of X. For most values of X, that will be the value undefined.
>
> If we want such default value initializers to actually mean anything we have to use a more complex definition of destructuring. Approximately:
>
> function hasProperty(obj,p) {
> // code that is equivalent to the ES5 [[HasProperty]] internal method
> // return obj.[[HasProperty]](p)
> }
>
> let _rhs = [,"one"];
> let a= (hasProperty(_rhs,0) ? _rhs[0] : 0), b=(hasProperty(_rhs,1) ? _rhs[0] : 1);
>
>
> The spec. I'm writing already takes care of all of these cases. My main point above, is that thinking of desugaring as just a simple assignment is a naive view that doesn't take into account all the bells and whistles that have been added to it since Lars' original implementation at Opera.
Very interesting. Still seems orthogonal to the decision whether or not to coerce the rhs to array (whatever that means). If []= is considered an “array operator” then coercion seems in line with how other operators behave.
If I wanted to ignore the length property, I would use:
let { 0: a, 1: b } = someValue
--
Dr. Axel Rauschmayer
axel at rauschma.de
home: rauschma.de
twitter: twitter.com/rauschma
blog: 2ality.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20111106/7db64d8e/attachment.html>
More information about the es-discuss
mailing list