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

Updated Wildcard patterns #5950

Closed
wants to merge 1 commit into from
Closed

Conversation

atsansone
Copy link
Contributor

Fixes #5926

@atsansone atsansone added the review.tech Awaiting Technical Review label Jun 28, 2024
@atsansone atsansone requested a review from eernstg June 28, 2024 16:52
@dart-github-bot
Copy link
Collaborator

Visit the preview URL for this PR (updated for commit 0c1b4c2):

https://dart-dev--pr5950-fix-5926-zuktzgms.web.app

Copy link
Member

@eernstg eernstg left a comment

Choose a reason for hiding this comment

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

I tried to suggest a different ordering of the text. It is a little bit tricky because it would be nice to have the two examples (List _ vs. List()) near to each other. However, it also seems useful to have the object pattern example in the object pattern section, and the wildcard example in the wildcard section.

So my comments are surely not in a usable shape yet, but I hope they can be used to take the next step.

@@ -438,27 +438,39 @@ If an object has extra fields that the pattern doesn't destructure, it can still

## Wildcard

`_`
`_`
`<type>()`
Copy link
Member

Choose a reason for hiding this comment

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

I think most of this needs to go into the '## Object' section.

First, note that _ is a wildcard, but <type>() is not.

On the other hand, <type>() isn't precisely the syntax of an object pattern, but it does overlap significantly (for instance, int() is an object pattern; in contrast, we can't use void Function({String s})() as an object pattern, even though void Function({String s}) is a <type>).

The old text below is not very informative, but a wildcard is an identifier pattern in its own right (as in switch (e) { _ => 1 } or var (_, _) = (2, 3);). We can add a keyword or a type to make it a variable pattern. For example:

void main() {
  switch (1) { case var _: break; }
  switch (1) { case final _: break; }
  switch (1) { case int _: break; }
}

We might want to make lines 443-444 a bit more explicit or detailed, but otherwise I think they do convey the correct information. So we could just leave them unchanged.

Comment on lines +446 to +458
These patterns can either be a [variable pattern](#variable) (`_`) or
[identifier pattern](#identifier) (`<type>()`).

* Object patterns are more concise and convenient,
even more so with generic types.
With generic types, an object pattern (`MyType()`) infers the
most specific type arguments from the matched value.
* A variable pattern (`MyType _`) uses less specific, often dynamic,
type arguments.
* With non-generic types, there's no reason to prefer variable patterns.

When you need a subpattern to destructure later positional values,
use a wildcard as a placeholder. This example uses a variable pattern.
Copy link
Member

Choose a reason for hiding this comment

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

Line 446-447 in the old text could also be kept unchanged (the new text doesn't really fit in this section).


<?code-excerpt "language/lib/patterns/pattern_types.dart (wildcard-typed)"?>
```dart
switch (record) {
case (int _, String _):
case (int(), String()):
print('First field is int and second is String.');
}
```
Copy link
Member

Choose a reason for hiding this comment

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

Again, I think it would be OK to keep lines 455-464 from the old text unchanged.

What I wanted to propose in #5926 was actually that there should be an extra paragraph here at the end of this section, perhaps something like the following:


This approach works fine for non-generic types like int and String. However, if you wish to test whether the matched value has a generic type then you need to specify the type arguments explicitly. The section about object patterns shows how you can use object patterns to infer the type arguments, which may be both more convenient and safer. Here is an example:

Iterable<int> iter = [2, 3, 4];
switch (iter) {
  case List<int> _:
    print('It was a list whose first element is ${iter[0].isEven}');
}

If we had used case List _: rather than case List<int> _: then it means case List<dynamic> _:, which in turn means that iter does not get promoted, and iter[0] is a compile-time error.


Then we could have something like the following at the end of the 'Object' section:


An extreme example is the case where the object pattern doesn't specify any properties at all. In this case the object pattern amounts to a type test. It is particularly useful in the case where the given type is generic, because the actual type arguments are inferred from the static type of the matched value. For example:

Iterable<int> iter = [2, 3, 4];
switch (iter) {
  case List():
    print('It was a list whose first element is ${iter[0].isEven}');
}

The object pattern List() is inferred to mean List<int>() because the static type of iter is Iterable<int>, and this means that the invocation of iter[0].isEven is type correct.

Hence, it may be a good habit to use an "empty" object pattern like List() when you just want to test the type of the matched value, rather than using a wildcard like List<int> _.


@RedBrogdon
Copy link
Collaborator

I'm going to close this for now. This change will likely be picked up again at a later date, with attribution back to this PR.

@RedBrogdon RedBrogdon closed this Jul 31, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
review.tech Awaiting Technical Review
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add recommendation to Wildcards on 'Pattern types' page
4 participants