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

Wildcard variables #3712

Open
munificent opened this issue Apr 18, 2024 · 4 comments
Open

Wildcard variables #3712

munificent opened this issue Apr 18, 2024 · 4 comments
Assignees
Labels
feature Proposed language feature that solves one or more problems wildcard-variables The wildcard-variables feature

Comments

@munificent
Copy link
Member

munificent commented Apr 18, 2024

Admin comment: this is being implemented, feature specification, implementation issue.

Pattern matching brought a new way to declare variables. Inside patterns, any variable whose name is _ is considered a "wildcard". It behaves like a variable syntactically, but doesn't actually create a variable with that name. That means you can use _ multiple times in a pattern without a name collision.

That leads to an irregularity:

var (_, _) = (1, 2); // OK.

var _ = 1;
var _ = 2; // Error. Already a variable in scope with this name.

Also, it's annoying that _ binds a name. When you have a lambda with more than one parameter that you don't use, you end up having to do:

takesCallback((_, __, ___) { ... });

I have a proposal to fix both by saying that local variables and parameters named _ are also non-binding. This is the tracking issue for that proposal.

@mit-mit mit-mit added the feature Proposed language feature that solves one or more problems label Apr 18, 2024
@Mike278
Copy link

Mike278 commented Apr 18, 2024

I always love seeing those usage-pattern breakdowns across huge corpuses of Dart code!

From the proposal:

From skimming some of the examples, it does look like some users sometimes name lambda parameters _ and then use the parameter in the body.

As one of those users I just wanted to add that my two use cases for doing this are to workaround #8 (unless there's a better issue to reference?)

xs.map((_) => _.isEven);
// vs
xs.map(.isEven); // strawman syntax

and #3001:

users.map((_) {
  final (user, selected) = _;
  ...
})
// vs
users.map((user, selected) {
  ...
})

@lrhn
Copy link
Member

lrhn commented May 21, 2024

I've tried to hunt down the places in the specification that would need to change to make wildcard variables work.
It's not as many as one could fear, but then, I probably didn't find all of them.

Collected here: https://gist.github.com/lrhn/c14c76c665a1e20f42e283d1fe6e6e02

Those changes (plus the similar places I've missed) should simply make _-named local declarations or type variables not introduce any name into the surrounding scope. That makes it not an error to have two declarations named _, since the error comes from adding them in the same scope, and there is nothing extra to do.

(If we get #3807, more changes are needed, to not make it an error for an optional parameter named _ to not have a default value. That'd also be a behavior where not having a name is materially different from having an implicit fresh private name.)

@munificent
Copy link
Member Author

As one of those users I just wanted to add that my two use cases for doing this are to workaround #8 (unless there's a better issue to reference?)

xs.map((_) => _.isEven);
// vs
xs.map(.isEven); // strawman syntax

Yeah, it's not an unreasonable use of _. But I think the best workaround today is to just give the parameter a real but short name.

@lrhn
Copy link
Member

lrhn commented Aug 22, 2024

I have no issue considering xs.map((x) => x.isEven) idiomatic code.

Short names are allowed for iteration variables. Nobody complains about for (var i = 0; i < 10; i++), and they shouldn't complain about values.map((v) ...) or elements.forEach((e) { ... }) either.
Long names are long, and sometimes a single letter is a perfectly reasonable way to identify a value, if there is no ambiguity about what it means.
It's not an abbreviation (which you should avoid), it really is just a brief and unambiguous name for a transient value.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Proposed language feature that solves one or more problems wildcard-variables The wildcard-variables feature
Projects
Status: Being implemented
Development

No branches or pull requests

5 participants