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

Closed
munificent opened this issue Apr 18, 2024 · 10 comments
Closed

Wildcard variables #3712

munificent opened this issue Apr 18, 2024 · 10 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, experiment flag wildcard-variables.

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.)

@mit-mit mit-mit moved this to Being implemented in Language funnel May 27, 2024
@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.

@mit-mit
Copy link
Member

mit-mit commented Feb 20, 2025

We should probably update https://dart.dev/effective-dart/style#prefer-using-_-__-etc-for-unused-callback-parameters as part of this feature? cc @munificent

Added dart-lang/site-www#6446 to track

@mateusfccp
Copy link
Contributor

BTW, shouldn't this issue be closed?

@mit-mit
Copy link
Member

mit-mit commented Feb 20, 2025

We probably should. @kallentu are you aware of any further wrap-up work, or can we consider it done?

@FMorschel
Copy link

Note, issue on definition of strict_inference and wildcard variables here:

Also we had this problem related to wildcard variables and if you've not close to main on your SDK, this might still be happening for you (the CP has landed already):

@kallentu
Copy link
Member

We probably should. @kallentu are you aware of any further wrap-up work, or can we consider it done?

There is some follow up work needed for the feature:

I'm working on them at the moment, so they will be completed soon.
I'd consider the actual feature complete though. These are bugs that have surfaced post-ship.

@kallentu
Copy link
Member

Finished the work for the two issues I've linked above.

Let's close out this issue 🚀 If any other bugs arise, I'll keep track of those, but in general -- we're good to go here.
Wildcard variables are in Dart 3.7!

@mit-mit mit-mit moved this from Being implemented to Done in Language funnel Feb 26, 2025
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: Done
Development

No branches or pull requests

7 participants