An array destructing specification choice

Lasse Reichstein reichsteinatwork at gmail.com
Mon Nov 7 00:59:42 PST 2011


On Sat, Nov 5, 2011 at 10:41 PM, Brendan Eich <brendan at mozilla.com> wrote:
> We have:
>
> 1. Should an array pattern always query 'length'?
>
> 2. If the answer to (1) is "no", then should ... in an array pattern query 'length'?
>
> On reflection and at this point in the thread, with your reply in mind, my prefs in order: [no, yes], [no, no]. In no case do I favor [yes]. I'm refutably matching [no, _] :-P.

My initial intuition was [no, ?], since that was without considering
rest-matching. With rest-matching, and me being a sucker for
consistency, I'm now leaning towards [yes, yes].

The possibilities are
 [no, no]
 [no, yes]
 [yes, no]
(since [yes, no] makes absolutely no sense).

[no, no] is definitly possible. It needs to be defined which
properties are included by the ... in, say [x,y,...r], but since the
result in z must be an array, it would seem that any array index
property of the RHS where you can subtract 2 and still be an array
index, is a candidate.

[no, yes] is also possible, but seems inconsistent if
  [x,y,z] = {0:0,1:1,2:2, length:2}
makes z be 2, but
  [x,y,...z] = {0:0,1:1,2:2, length:2}
doesn't make z be [2].

[yes, yes] means always treating the RHS as an array-like object,
respecting the length property.


Both [no, no] and [yes, yes] are consistent. Either the result always
depends on "array-like-ness" of the RHS or it never does, i.e., either
it reads the length and converts it to an UInt32 (or Integer), or it
doesn't.

If the object being destructured is in fact a plain Array, with no
inherited elements above the length, then there is no difference.
This is most likely the (very) common use case. This is what the ES
programmers' intuition will be based one.

So the question is which behavior we would want for something that
breaks the array-like-contract - treat it as a plain object (ignore
length), or treat it as an array-like object (ignoring properties
above length). We must do one of them, and not both, because they are
mutually exclusive.

Both can cause errors if the programmer does it wrong, if you have an
almost-array-like object. Which is the correct behavior depends on
what was *intended*: to be array-like or not.

The original question was what an ES programmer would expect.
I think he will probably expect array-like deconstructors to treat the
RHS as an array(-like object).
I.e., [yes,yes].

That also have the advantage of actually providing otherwise
unavailable functionality.
You can write {0:x, 1:y, 2:z} instead of [x,y,z] if you want
object-behavior, but if they are the same, you can't get array-like
behavior.

Arrays are just an abstraction in ECMAScript, which all the
Array.prototype methods that are "intentionally generic" proves. If it
quacks like an Array and swims like an Array, we allow ourselves to
treat it like an Array.

I.e., I think the most easily comprehensible behavior is to make array
destructuring treat the RHS as an Array.
It matches the common use-case (actual arrays), it is consistent (does
the same whether you use ... or not), and is easily explainable.

/L


More information about the es-discuss mailing list