tc39 / proposal-pattern-matching

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

Statement version of match expression #294

Open Jack-Works opened 1 year ago

Jack-Works commented 1 year ago

The plan we already have is to wait for https://github.com/tc39/proposal-do-expressions advance.

I've heard that the author has lost interest on that proposal, maybe we should consider what if we will never have do expression.

A possible solution is to have MatchExpression and MatchStatement, where MatchStatement can contain other statements.

for (const expr of exprs)
    match (expr) {
        default: { continue };
        //       ~~~~~~~~~~~~ block in statement position
    }

for (const expr of exprs)
    x = match (expr) {
        default: { continue };
        //       ~~~~~~~~~~~~ object literal in expression position
    }
ljharb commented 1 year ago

I'm still interested in seeing do expressions advance, and I think we could do a follow-on match statement proposal later if it's indeed deemed to be something that will never happen.

hax commented 1 year ago

It's really bad that default: { value } would change semantic if people add/remove x = before match.

Personally I think the thing after default: should always a statement, to be consistent with default: in switch or label: syntax. (Actually case X: and default: are just special label as the original source of the syntax from C). This might one of the small reason why Java choose adding case X -> expression syntax.

ljharb commented 1 year ago

I agree that would be bad; that’s not what I’d expect we’d do.

This proposal is explicitly not trying to follow the many broken choices of switch (and if consistency with “label” occurs to someone, that’s a strong argument to not use the colon at all).

tabatkins commented 1 year ago

Right, the current plan is that the match expression continues with its current semantics and requirement that the match arms are expressions. If do-exprs never advance, we'll add something to match expression to allow statements in there.

Personally I think the thing after default: should always a statement,

Oh gosh absolutely not, the default branch shouldn't use a different parsing context to every other branch. "Consistent with switch" is not only an anti-goal here, it's not coherent anyway; switch has default: <statements-here> because it also has case foo: <statements here>. The consistent position for the match expression is to also have expressions in both when foo: <expression> and default: <expression>.

theScottyJam commented 1 year ago

If do expressions to not advance and we were to add something to pattern matching so you could do statements in the RHS, would we also consider allowing some way for this "RHS block" to provide a completion value, the same way you can do with do expressions?

If so, we're basically replicating the functionality of do expressions with pattern matching, in fact, you could basically build-your-own clunky do expression with return match (null) { when (null) { ...look at me, I'm basically a more-verbose do expression } }. And, I sort-of doubt that would fly if do-expressions don't achieve consensus (though, we'd have to see).

If not, it's a bit of a shame - it basically encourages you to resort to IIFEs if you need your block to have a completion value, as the syntactic alternative pattern-matching provides wouldn't be powerful enough for these kinds of use cases.

ljharb commented 1 year ago

Yes, that’s what I’d envision - a follow on to add do expressions only in the RHS of a when.

hax commented 1 year ago

@tabatkins Yes you are inventing consistent "when:" and "default:" but it doesn't change the fact that "default:" in match is inconsistent to "default:" in switch, not only JS, but also all mainstream C family "default:".

hax commented 1 year ago

Note, do expression (as current do expression draft) never solve default: inconsistent issue, because do expression can't be put in the place of statement. default: do { ... always be parsed as do while not do expression if keep consistency.