Dot Shorthand for Object Destructuring
Summary
Introduce a shorthand for object destructuring where the type name can be omitted when it can be inferred from the right-hand side, using a leading dot (.).
Motivation
Object destructuring currently requires repeating the type name even when the matched expression already provides it, leading to unnecessary verbosity:
final Point(:x, :y) = Point(1, 2);
Proposal
Allow using a dot-prefixed object pattern whose type is inferred from the value being matched:
final .(:x, :y) = Point(1, 2);
This behaves the same as explicitly writing Point(:x, :y) but without repeating the type.
Examples
// current
final Size(:width, :height) = size;
// proposed
final .(:width, :height) = size;
// current
LayoutBuilder(
builder: (context, constraints) {
final BoxConstraints(:maxWidth, :maxHeight) = constraints;
// ...
},
);
// proposed
LayoutBuilder(
builder: (context, constraints) {
final .(:maxWidth, :maxHeight) = constraints;
// ...
},
);
// current
GestureDetector(
onPanUpdate: (details) {
final DragUpdateDetails(delta: Offset(:dx, :dy)) = details;
// ...
},
);
// proposed
GestureDetector(
onPanUpdate: (details) {
final .(delta: .(:dx, :dy)) = details;
// ...
},
);
I think this is better than what we have currently (writing the type out fully), but I think we can go all the way and removing any prefix entirely. (Related: https://github.com/dart-lang/language/issues/4124 https://github.com/dart-lang/language/issues/2563)
My preferred approach for this is still #2563 because it's maximally terse. You're right that we could use a leading . similar to dot shorthands, but that feels like a weird fit here. With dot shorthands, the syntax that you are abbreviating has a dot in it. When you turn Color.red into .red, it makes sense for there to be a dot there because there was in the longer code. You just eliminated the preceding identifier.
But in a pattern, going from Color(red: _) to .(red: _) makes less sense. There was never a . there, so why summon one in the abbreviated form?