(This is a follow-up to Placeholder Syntax)
Can we get placeholder syntax in Rust?
One of the things I really miss from Scala is the placeholder syntax, and I'd love to see at least a limited version of it in Rust.
To plagiarize this 2021 post on the topic, the syntax lets you transform code like this:
users .iter() .filter(|x| mypredicate(42, x)) .map(|x| x.name) .collect();
users .iter() .filter(mypredicate(42, _)) .map(_.name) .collect();
Semantically, all it does is replace the underscores (the anonymous arguments) with named closure arguments, so
foo(_) desugars to
_.bar desugars to
_.baz(_) desugars to
|x, y| x.baz(y), etc.
Besides automatically providing an elegant partial application syntax, I love this syntax because it allows me to avoid naming things that don't need to be named, which would otherwise detract from the logical flow of the code. Code should be simple, and simple code shouldn't contain irrelevant details.
When this was previously discussed in 2021 the main apparent blocker was how the closure arguments would be scoped, e.g. this post.
But, I think this is a solved problem - just use the same rule as Scala. Specifically, bind at the level of the closest outer scope. Or, to quote from the Scala semantics:
eof syntactic category
Exprbinds an underscore section
u, if the following two conditions hold: (1)
u, and (2) there is no other expression of syntactic category
Exprwhich is properly contained in
eand which itself properly contains
foo(bar(42, _)) becomes
foo(|x| bar(42, x)).
The previous thread considers the possibility that Scala's simple scoping rule wouldn't prove sufficiently flexible, and suggests elaborations.
I think the best idea was to use a special token, e.g.
|..|, as a scope marker.
I think it would work like this:
- If the scope marker is not present, default to Scala rules.
- Else, anonymous arguments are scoped to the level of their closest scope marker. E.g.
foo(|..| bar(baz(42, _)))would become
foo(|x| bar(baz(42, x))).
However, while I would like to elide argument names in arbitrarily nested scopes, it's not a hill I'm willing to die on, and I'm open to the criticism that this special syntax doesn't added enough benefit to justify its inclusion.