tc39 / proposal-pattern-matching

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

Why is `if` a guard instead of a combinator? #255

Closed erights closed 7 months ago

erights commented 2 years ago

Why is if a clause guard instead of a pattern combinator, like and, or, and with?

ljharb commented 2 years ago

Because if doesn’t use a pattern, it takes an expression and tests its truthiness - so it wouldn’t make sense for it to be a combinator.

erights commented 2 years ago

Ok, let's drop the term "combinator". What I'm really asking is if the equivalent of the following grammar would make sense

<pattern> ::=
  <pattern> ("and" <pattern>)+
  <pattern> ("or" <pattern>)+
  <pattern> ("with" <pattern>)+
  <pattern> ("if" "(" <expr> ")")+
  "if" "(" <expr> ")"
  <simplerPattern>;

Then you could nest the if in relevant subpatterns, just like the others.

theScottyJam commented 2 years ago

Is there value in nesting the if? It seems anything you can do with a nested if can be easily extracted out and placed after the pattern-matching, without sacrificing anything.

erights commented 2 years ago

It seems simpler to me to get rid of the guard concept.

A nested if can stop matching earlier, enabling patterns after that depend on the if condition succeeding. (just like a short circuiting && in the expression grammar enables us to use expressions on the right that are only non-erroneous if the expression on the left was truthy.)

Once this proposal moves forward, I expect that the <pattern> grammar will find other uses. I would like the if functionality to be part of that, rather than needing to use the clause-lhs for that.

Really, the first reason is the big one for me. You already have a compositional notion of pattern. Use that rather than introducing a new concept.

ljharb commented 2 years ago

Thanks for clarifying. I can see arguments that suggestion that makes it more complex, and also arguments that it makes it simpler.

Where do you envision the pattern grammar to find other uses?

theScottyJam commented 2 years ago

If short-circuiting is an argument, would there also be use cases for having an if before the pattern even starts?

For example, something like this (not sure how the syntax would actually work)

match(thing) {
  when(...): ...
  when(if (matcher != null) & { x: ${matcher} }): ...
}
mpcsh commented 2 years ago

Two thoughts:

ljharb commented 2 years ago

This seems answered for now; @erights, are you satisfied to close this? Or, if not, are you content to consider it a stage 2 concern as opposed to a stage 2 blocker?

erights commented 2 years ago

Although I do not consider this adequately answered, I agree it is not a stage 2 blocker.

tabatkins commented 2 years ago

And note that we can safely add a combinator-level if() in the future; nothing in the grammar should conflict with that.

ByteEater-pl commented 1 year ago

@theScottyJam, this seems easy, just add _ before if. It's really arbitrary nesting that's the added value @erights proposes.