fail-fast object destructuring (don't add more slop to sloppy mode)

Andreas Rossberg rossberg at google.com
Wed Jan 16 09:22:20 PST 2013


> On Jan 2, 2013, at 7:58 PM, Brendan Eich wrote:
>
>> I think we can do this now. Allen should weigh in. Hope to hear from Andreas R. soon too!
>>
>> Apologies for the long thread, and thanks to Herby for interaction that clarified many things. Perhaps I should resummarize:
>>
>> The best new-new plan to avoid adding slop is to revise ES6 destructuring thus:
>>
>> 1. No ToObject(RHS).
>> 2. Exception on missing property selected without a ?-suffix.
>> 3. ?-suffix allowed on any pattern, imputing undefined deeply instead of refuting.
>> 4: the ? is a separate lexeme from the : in long-hand patterns.
>>
>> How's that?

[Sorry to be late, catching up from a 2 weeks off-line vacation. :) ]

Thanks Brendan for reviving the discussion. That plan mostly matches
what I was arguing for last time round (including the necessity to
allow ? on every pattern), so me likes. I still see some issues with
making ? postfix (readability, parsing), but that's a comparably minor
point.


On 4 January 2013 01:33, Allen Wirfs-Brock <allen at wirfs-brock.com> wrote:
> I'm fine with points 2-4.  However, I think no ToObject(RHS) would be a mistake.  Here's why:
>
> In almost all other situations where an object is needed, a primitive value (including a literal) can be used.  This includes contexts that use the dot and [ ] property access operators. Essentially, in all object appropriate situations primitive values act as if they were objects. This is important in that in most cases it allows ES programmers to ignore distinctions between objects and primitive values.
>
> Destructuring is frequently described as simply a de-sugaring over property access in assignments and declarations.
>
> let {length: len} = obj;
>
> is most easily explained by saying that it is equivalent to:
>
> let len = obj.length;
>
> But if the ToObject is eliminated from the RHS then this desugaring equivalence is no longer valid in all cases.  The obj.length form would work fine if the value of obj was a string but the destructuring form will throw.  This breaks the general ES rule that you can use a primitive value in any context where an object is required.  It is the sort of contextual special case that developers hate and which makes a language harder to learn. Consistency is important.
>
> Finally, note that now with exceptions on missing properties (without ?) it is likely that most situations where a primitive value is erroneously used on the RHS will throw anyway simply because the primitive wrapper probably won't have the requested property. So, removing the ToObject just creates inconsistency without adding much in the way of error detection.

All good points, and I think it makes sense to separate the discussion
of implicit conversion from refutability itself.

I think your argument presupposes an assumption that only happens to
hold for the pattern language currently proposed, but is unlikely to
remain so in the future: namely, that all patterns describe objects.
In particular, a pattern matching construct wants to allow, say,
strings, null, true and others as patterns, and surely you do _not_
want ToObject in those cases.

One defensible position might be to only invoke ToObject when actually
matching against an object/array pattern. But to be consistent, you'd
then have to do similar conversions for other patterns, too, e.g.
invoking ToString when matching against a string. Unfortunately, that
would make using a future pattern matching construct correctly much
harder and more tedious. For example, writing

  match (e) {
    case true: ...
    case null: ...
    case {x, y}: ...
  }

will take the first case for all objects, although that is unlikely to
be the intention, here or elsewhere. Similarly,

  match (e) {
    case {}: ...
    case
  }

runs into the first case for almost anything when the more natural
expectation may be only actual objects.

So I believe that in the context of patterns, implicit conversions
violate the principle of least surprise and are future-hostile (in
terms of usability) towards a more general pattern matching facility.

/Andreas


More information about the es-discuss mailing list