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

Roundup of proposed patterns on vblang #367

Open
zspitz opened this issue Dec 19, 2018 · 8 comments
Open

Roundup of proposed patterns on vblang #367

zspitz opened this issue Dec 19, 2018 · 8 comments

Comments

@zspitz
Copy link

zspitz commented Dec 19, 2018

As a follow-up to #337 (comment), this is a collection of proposed patterns described in the various issues related to pattern matching (#124 and #337).

@AnthonyDGreen's patterns:

Source Name Suggested syntax Recursive Comments
#124 wildcard * Matches all values, including Nothing
#124 variable identifier [?] [ As typename] Introduces a variable
The variable's type is that of the value to be matched, if not specified in the pattern
Without ?, match fails on Nothing
With ?, match succeeds on Nothing; the variable's type is nullable
#124 function identifier ( [ pattern1 [, pattern2 ...] ] ) Yes identifier is a Boolean-returning function, with 0 or many parameters
Sub-patterns can be used in place of ByRef parameters, whose value must match the corresponding pattern
Allows extending pattern matching (AKA F# active patterns)
#124 tuple ( pattern1 [ , pattern2 ...] ) Yes Matches a tuple of arity eual to the number of patterns specified, if each of the sub-patterns also match
#141 array { pattern1 [ , pattern2 ...] } Yes Matches an array with the specified number of elements, if each of the sub-patterns also match
#140 string interpolated string Yes Matches if the string can be deconstructed using the constant parts of the interpolated string
Interpolations are treated as sub-patterns which the variable strings are matched against
#139 XML XML literal Yes Matches an XElement if the XElement can be deconstructed based on the constant parts
Embedded expressions are treated as sub-patterns, which are matched against corresponding content
#124 JSON Yes Using some syntax similar to JSON literals in #101

Note: This set of patterns assumes the use of Matches (or some other dedicated keyword) in Case clauses.


@bandleader / @zspitz 's patterns:

Source Name Suggested syntax Recursive Comments
#337 expression expression Any arbitrary expression1
#337 comparison [Is] comparison-operator expression Matches if the comparison holds1
#337 like Like string-expression Matches if the value is Like the specified string expression1
#337 range expression To expression Matches if the value is between the two expressions1
#337 variable + typecheck Dim identifier [As typename] Introduces a variable into the pattern expression's child scope
The variable's type is that of the value to be matched, if not specified in the pattern
A value of Nothing matches if the variable's type can hold Nothing2
#337 typecheck As typename Matches if the value is of the given type
A value of Nothing matches if typename can hold Nothing2
#337 OR pattern, pattern Yes Matches if either sub-pattern matches1
#124 tuple ( pattern [, pattern ...] ) Yes Matches a tuple with the specified number of elements, and each element matches the corresponding sub-pattern3
#124 NOT Not pattern Yes Matches only if the value doesn't match the sub-pattern4
#124 with With {. identifier = expression ... }
With {. identifier Matches pattern ... }
Yes Matches if the value has public properties/fields with a property / public field whose value is equal to expression, or that matches pattern
Multiple properties/fields can be tested against

Footnotes:

  1. This set of patterns assumes Case pattern, without a dedicated keyword. Therefore, compatibility with existing Case syntax needs to be preserved.
  2. Hopefully, VB.NET will get non-nullable reference types; they can be used to exclude Nothing from reference types
  3. Because VB.NET supports Case expression, it's important that all patterns not be valid as expressions. For example, the following wouldn't compile: Dim a = Dim x As String, so Case Dim x As String unambiguously refers to a pattern. However, even though the tuple pattern could define an expression -- Dim a = (1, 2); because value tuples are a value type, the meaning is the same whether Case tuple is treated as a pattern or an expression; the ambiguity could be resolved by giving higher priority to the pattern meaning over the expression meaning.
  4. See the previous note. It will be necessary to determine if what follows the Not is a pattern or an expression, to know ifNot is to be a pattern or an expression. Nevertheless, I think there is enough value in the pattern to justify it.

Pinging @KathleenDollard @ericmutta @paul1956

@zspitz zspitz changed the title Summary of collected patterns for pattern matching Roundup of proposed patterns on vblang Dec 19, 2018
@zspitz
Copy link
Author

zspitz commented Dec 20, 2018

And the formal grammar of the second set of patterns:

Pattern
    // patterns with subpatterns
    : Pattern ',' Pattern                            // OR pattern
    | '(' Pattern (',' Pattern)* ')'                 // tuple pattern
    | 'Not' Pattern                                  // NOT pattern
    | 'With {' MemberPattern (, MemberPattern)* '}'  // with pattern

    // patterns without subpatterns
    | 'As' TypeName                          // typecheck pattern
    | 'Dim' Identifier ('As' TypeName)?      // variable + typecheck pattern
    | 'Is'? ComparisonOperator Expression    // comparison pattern
    | 'Like' StringExpression                // Like pattern
    | Expression 'To' Expression             // range pattern
    | Expression                             // expression pattern
    ;

MemberPattern
    : '.' Identifer Equals Expression
    | '.' Identifier `Matches` Pattern
    ;

@zspitz
Copy link
Author

zspitz commented Mar 15, 2020

How would the Not pattern work together with the OR pattern, without it being ambiguous with the tuple pattern? Do parentheses in a pattern mean a tuple, or grouping? IOW, what would this pattern:

Not (1, 5)

mean? Would it match only if the tested expression is not a tuple of (1, 5)? Or would it match only if the tested expression is neither 1 or 5?

@Happypig375
Copy link
Member

No And patterns?

@zspitz
Copy link
Author

zspitz commented Mar 16, 2020

Currently Case supports pattern , pattern as the OR pattern, which we have to keep for backwards compatibility; it's going to be hard to find something opposite that to represent And short of an explicit keyword.

Also, I think the AND pattern has less utility, as most of the patterns cannot be combined together. For example, trying to match something which is both a tuple (tuple pattern) and has a public LastName property is not possible. It might have use as a combination of Not patterns -- not a tuple, and not having a LastName property -- but that could easily be rewritten as Not on a pair of OR patterns -- not (a tuple or having a LastName property). OTOH, it might be important to allow both forms, to better express intent.

@zspitz
Copy link
Author

zspitz commented Mar 17, 2020

How would the Not pattern work together with the OR pattern, without it being ambiguous with the tuple pattern?

We could just disallow use of ( as a grouping construct within patterns. I don't really see any other choice as long as we want to allow ( for the tuple pattern.

@Happypig375
Copy link
Member

Maybe we can use this syntax:

  • Tuple pattern (pattern, pattern, pattern...)
  • Or pattern AnyOf(pattern, pattern, pattern...)
  • And pattern AllOf(pattern, pattern, pattern...)

@zspitz
Copy link
Author

zspitz commented Mar 17, 2020

Except that the current Or pattern doesn't require any keyword. It's probably a no-brainer that backwards compatibility must be preserved.

@Happypig375
Copy link
Member

Except that the current Or pattern doesn't require any keyword.

We can treat it as a special case when used at the top level.

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

No branches or pull requests

2 participants