tc39 / proposal-pattern-matching

Pattern matching syntax for ECMAScript
https://tc39.es/proposal-pattern-matching/
MIT License
5.5k stars 89 forks source link

Disallow { a } #325

Open Jack-Works opened 6 months ago

Jack-Works commented 6 months ago

Current spec does not allow { ...a }.

You have to write { ...let a } (bind rest to a) or { ...(a) } (test rest with a, where a might be a custom matcher) depends on your intension.

I think we should also do this to { a, b: 1 } to disambiguate { a: a, b: 1 } (match with a) with { b: 1} and has "a" (has a property in it).

Currently, { a } means and has "a".

Or we can do the other way, allowing { ...a } to be { ...(a) }.

tabatkins commented 6 months ago

You have to write ... { ...(a) }

That shouldn't be required. {...a} is perfectly fine - it makes an object holding the remaining properties, then tests it against the a pattern. Where are you seeing the restriction that requires parentheses?

Jack-Works commented 6 months ago

@tabatkins it's in the spec as a not-consensused-yet feature. I identified them as footguns and therefore included them in the spec. { ...a } in a pattern has slightly different meaning with in the destructing, therefore it's better to ban it and require explicit clarify of what developer means (a) or let a

img
ljharb commented 6 months ago

I'm confused, what else would { ...a } mean other than { ...a: a }?

Jack-Works commented 6 months ago

I'm confused, what else would { ...a } mean other than { ...a: a }?

It means collecting rest properties in the destructing and binding it to a variable out of pattern matching. Developers might think it has the same meaning inside pattern matching.

const { x, ...rest } = obj
if (obj2 is { y, ...rest2 }) {
    // ?? y and rest2 are not bindings!!
}
ljharb commented 6 months ago

How is that different from any other object destructuring pattern?

Jack-Works commented 6 months ago

In my example, x and rest is a binding, but y and rest2 is not.

ljharb commented 6 months ago

Yes, I agree this is a difference between destructuring and pattern matching - it has nothing to do with rest properties or with the concise form, though.

If we don't want that discrepancy, we'd need to revert to our previous version that had ${} and implicit bindings, which already got pushback.

tabatkins commented 6 months ago

Yeah, {...a} is as different between pattern-matching and destructuring as {a} is. Both are consistent with their own rules, where the ident in ...foo is interpreted the same as the value in {key: foo} - in pattern-matching it's a pattern in both places, and in destructuring it's a name binding in both places.

It would be fairly bad to change this, imo.

55Cancri commented 6 months ago

Is pattern matching waiting for do expressions to be implemented? There seems to be a lot of activity for pattern matching but not much progress. What really is the bottleneck? How can I help?

If JavaScript had pattern matching and let expressions like rust, it would significantly improve the quality of the code by making it more concise and expressive. Switch statements, if statements, and decision tables are all too cumbersome.