Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add pattern matching #251

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open

Conversation

JLHwung
Copy link
Contributor

@JLHwung JLHwung commented Jun 18, 2021

View Rendered Text

See also AST examples for this PR.

This PR adds support to the Pattern matching proposal. Besides the match () {} expression, the proposal introduces the concept of MatchPattern, which has subtle differences with current destructuring Pattern. I copied current Pattern design and infix the Node type with Match. I am open to changes of AST structures or renaming of AST node shapes.

}
```

## RestMatchElement
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ArrayMatchPattern, ObjectMatchPattern and RestMatchElement are essentially ArrayPattern, ObjectPattern and RestElement with Pattern replaced by MatchPattern.

```js
interface AsMatchPattern <: MatchPattern {
type: "AsMatchPattern";
test: MatchPattern;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The AsMatchPattern is separated from BinaryMatchPattern because the right (renamed as id) accepts a Pattern, not MatchPattern.

```js
interface BinaryMatchPattern <: MatchPattern {
type: "BinaryPattern";
operator: "and" | "or" | "with";
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The champions have not decided the combinator token of "and" and "or": tc39/proposal-pattern-matching#179. We could change to & and | here if they go with these sigils.

Comment on lines 84 to 90
## ExpressionMatchPattern
```js
interface ExpressionMatchPattern <: MatchPattern {
type: "ExpressionMatchPattern";
expression: Expression;
}
```
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure if this is covered or not; the syntax allows ^Identifier, ^(Expression), but also things of the form ^A['B'].C() or ^A?['B']?.C?.().

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does it matter if there are parentheses or not?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes; any expression can be in parens, but only a specific limited set of forms can omit them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the syntax allows ^Identifier, ^(Expression), but also things of the form ^A['B'].C() or ^A?['B']?.C?.().

Both ^Identifier and ^(Expression) are an ExpressionMatchPattern whose expression is an Identifier or an Expression. ESTree does not track whether parentheses are required to form a valid syntax. Instead a parser will throw when parentheses are required and a generator will add parentheses based on the AST structure.

extend interface UnaryExpression <: Expression, MatchPattern {}
```

If a UnaryExpression is a MatchPattern, its `operator` must be `"-"`, its `prefix` must be `true`, and its `argument` must be either a Literal with numeric value, or an identifier named `"Infinity"`.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as a pattern, this also allows undefined (even if the identifier resolves to something that's not the undefined value), but also, all number and bigint literals (with +, -, or no sign at all), null, booleans, etc.

Also, template literals haven't been thought out here - i filed tc39/proposal-pattern-matching#205 to track

Copy link
Contributor Author

@JLHwung JLHwung Jun 21, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, undefined is covered in the Identifier case

extend interface Identifier <: Expression, Pattern, MatchPattern {}

The UnaryExpression case is addressed to things like -0, -1, -1n and -Infinity, since they are an UnaryExpression from the AST perspective.

The template literals in ESTree has a specific type TemplateLiteral, in this PR the TemplateLiteral is not mentioned so it is not a MatchPattern. But yeah it is a good question whether it should be allowed. I will update this PR if necessary.

Copy link
Contributor

@nzakas nzakas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good. I haven’t had the time to dig in and explore the proposal at any depth but hope too soon.

experimental/pattern-matching.md Outdated Show resolved Hide resolved

If `test` is `null`, `id` must be `null`.

## MatchPattern
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we add a mention here as to why we don’t just use Pattern? (You mentioned in the PR itself but seems important to include here as well.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, addressed in d67b89a.

}
```

## 4 "if" Match Clause and Binary Match Pattern
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: missing dots here and below in headings.

@@ -0,0 +1,373 @@
# AST examples of [Pattern Matching ESTree Proposal](proposal-pattern-matching-estree)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not keep this as a section in the main .md?

Copy link
Contributor Author

@JLHwung JLHwung Jul 5, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh the examples are not supposed to be part of the spec. They serves as an explainer only. I should have removed them before commit.

@RReverser
Copy link
Member

It's rather hard to understand which of the conversations here are still unresolved. Is there anything left?

@ljharb
Copy link

ljharb commented Aug 5, 2021

It's worth noting that the syntax is still in flux; for example, we'll probably go with and/or for combining patterns, and it's possible we'll drop as entirely.

@nzakas
Copy link
Contributor

nzakas commented Aug 6, 2021

@JLHwung can you mark conversations as resolved so we can see what’s left to discuss here?

@ljharb this is being submitted to the experimental folder, so we aren’t committing forever, just to have a format we can work with at least in the short term

@JLHwung
Copy link
Contributor Author

JLHwung commented Aug 6, 2021

it's possible we'll drop as entirely.

Yeah the AST spec tries to cover all the mentioned syntax. If we drop some features when the proposal gets advanced, we can revise the AST accordingly. The experimental folder is deemed unstable and we are free to make breaking changes.

I have resolved current review issues. Let me know if there's more. I am on vacation and will come back to work on it next week.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants