dart-lang / dart-lang/language
Introduce `let` construct for local destructuring
- Dominant language
- TeX
- Stars
- 2.9k
- Forks
- 239
- Avg merge
- 2d 18h
- Merged PRs (30d)
- 14
Description
With pattern destructuring, we treat *declarations* specially.
You can write
```dart
var (x, y) = pair; // grammar: `var` bindingPattern `=` expression
print(x + y);
```
but that doesn't easily let you destructure inside an expression, because declarations are not inside expressions.
So, let's introduce:
```dart
`let' bindingPattern `=' expression `in' expression
```
(possibly allow a comma-separated list of "pattern `=` expression" instead of requiring you to nest `let`s).
The use cases would be `=>` functions:
```dart
class C {
(double, double) pair;
int get first => let (first, _) = pair in first;
}
```
or, more importantly, inside collection literals:
```dart
{for (var c in cs) let (first, second) = c.pair in first: second}
```
The grammar has no end-token, which means that it'll likely need to have a low precedence, and will need to be parenthesized if used inside more complex expressions, which is very likely what's best for readability too.
```dart
var x = let (first:, last:) = list in "$first, ..., $last";
// but
var z = x + y + (let w = calculate(x, y) in w * w) + q;
```
The scope of the variable will only be the `in`-expression (or following bindings if we allow more than one:
```dart
let x = 1, y = x + 1 in y + 2
```
Should the variables be *final*? Or do we want a mutable variable. The latter seems occasionally useful, like:
```dart
Map toMap(Iterable iterable) => {let x = 0 in for (var y in iterable) x++: y};
```
You can always *not* assign to a variable, so being mutable seems like the best default.
People wanting extra safety against accidental mutation can write `let final x = ..., in ...`.
Probably means `let` needs to be at least a built-in identifier, and probably a reserved word.
Contributor guide
Assessment
This issue has not been assessed yet.