Andreas Rossberg wrote:
Well, note my careful use of the conjunctive. :) That basically was the question I initially asked. My viewpoint is: If there is some reasonable chance that we might add pattern matching at some point in the future, then yes, I think we should not be future hostile, and bear that equivalence in mind as important.

    We could try to have our cake and eat it, by extending the pattern
    language with prefix-! or prefix-?. Which prefix depends on the
    choice of default behavior, based on ranking of the two
    equivalences. Whatever that ranking, does this make sense so far?


Sure, I'm all for that. As long as they -- and the rest of the pattern language -- have the same meaning in all contexts.

Ok, we are getting somewhere -- thanks for bearing with me (and I hope this thread was helpful to others following, as it was to me).

Then the question is: should we value the current equivalence more and make the pattern-matching equivalence use-case pay the prefix-! syntax. IOW, keep

A:

  let {foo} = bar();
  =~
  let foo = bar().foo;

and impute undefined if foo is missing in the object returned by bar(), and require

  { let {!foo} = exp; console.log(foo) }
  =~
  match (exp) { case !foo; console.log(foo); }

Without the !, the match would bind undefined to the case foo local.

Or should we do as you propose, and require prefix-? to get the impute-undefined-on-missing-property behavior needed for the first equivalence, call it

B:

  let {?foo} = bar();
  =~
  let foo = bar().foo;

At least this way, match does not need ! to work as pattern-matching users expect:

  { let {foo} = exp; console.log(foo) }
  =~
  match (exp) { case foo; console.log(foo); }

Allen rallied me to the prefix-! route by objecting that prefix-? would not be available outside of patterns, which simply highlights how JS already imputes undefined for missing property.

I feel the burden of the first equivalence acutely, since I implemented destructuring per the ES4-era proposal to look like (A) above, based on Opera's engine of the time, and Rhino and probably other engines followed suit. This experience means compatibility breaking pain, and what's more: user-testing something new, unscientifically as ever but in much less time than we've had to hear about bugs due to (A).

However, I agree that requiring prefix-! in

 match (exp) { case !foo: ... }

is onerous if we choose the impute-undefined path, and worse: that a missing prefix-! is both likely to happen (a footgun), and nonsensical for pattern matching.

So (B) wins if we want pattern-matching.

We should talk more at this month's TC39 meeting, but I see a sharp divide ahead:

1. Choose (A), possibly with modification, either rejecting useful pattern matching decisively, or else making its pattern language differ by making prefix-! implicit. But you rejected splitting pattern meaning across destructuring and future pattern-matching, in the last sentence cited above.

XOR

2. Choose (B) because future-proofing for pattern matching wants prefix-?, and impose a compatibility break from what we and others implemented, and what most JS users might expect based on JS's carefree imputing of undefined.

Comments from es-discuss peanut gallery welcome.

I could go for 1/A, except for two facts. First, I believe there is a non-trivial body of Firefox JS that depends on imputing undefined. Second, and what is more important: we haven't usability-tested 2/B at all.

/be

_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to