Skip to content

Instantly share code, notes, and snippets.

@eernstg
Last active November 7, 2025 16:23
Show Gist options
  • Select an option

  • Save eernstg/1310863683c15edf17eb99d06988e646 to your computer and use it in GitHub Desktop.

Select an option

Save eernstg/1310863683c15edf17eb99d06988e646 to your computer and use it in GitHub Desktop.
// Only supported in the analyzer at this time.
// Use `--enable-experiment=anonymous-methods`.
// ----------------------------------------------------------------------
// Example from Sam Rawlins, discussed in chat.
// Original code.
Bucket? get _daysToFirstConversion =>
(_forecastRpcState?.performanceForecast?.hasDaysToFirstConversion() ??
false)
? _forecastRpcState!.performanceForecast!.daysToFirstConversion
: null;
// Using an anonymous method.
Bucket? get _daysToFirstConversion =>
_forecastRpcState?.performanceForecast?.=> hasDaysToFirstConversion()
? daysToFirstConversion
: null;
// Helpers.
typedef Bucket = int;
class A {
B? get performanceForecast => B();
}
class B {
bool hasDaysToFirstConversion() => true;
int get daysToFirstConversion => 1;
}
A? _forecastRpcState = A();
// ----------------------------------------------------------------------
// "Open" an object, somewhat similar to Pascal `WITH` blocks.
class Point {
final int x, y;
Point(this.x, this.y);
}
final p = Point(3, 4);
final ex1a = p..{ print(x + y); };
void ex1b() {
var sum = p.=> x + y;
}
// ----------------------------------------------------------------------
// "Open" a record type.
final r = (x: 3, y: 4);
void x2() {
var sum = r.=> x + y;
(3, 4).{ print($1 + $2); };
}
// ----------------------------------------------------------------------
// Run code conditionally (only when not null).
String? f3() => 'Hello!';
final ex3a = f3()?..{ print(length); };
final ex3b = f3()?..(s) { print(s.length); };
void ex3c() {
f3()?.{ print(length); };
var b = f3()?.(s) {
print(s.length);
return s.length > 4;
} ?? false;
}
// ----------------------------------------------------------------------
// Emulate a `let` expression.
void ex4() {
int x;
// Using the arrow form.
x = 42.(i) => 'Hello'.(s) => true.(b) => b ? i : s.length;
// Same thing, using the block form.
x = 42.(i) {
return 'Hello'.(s) {
return true.(b) {
return b ? i : s.length;
};
};
};
// Note that cascades are at a lower precedence level than anonymous
// methods, so this must have explicit parentheses:
int result = 1..(i) => ('Hello'..(s) => (true..(b) => (b ? i : s.length)));
// But the block form leaves no doubt about where the block ends:
result = 1..(i) {
'Hello'..(s) {
true..(b) {
b ? i : s.length;
};
};
};
}
// ----------------------------------------------------------------------
// Make cascades more flexible.
void ex5() {
String s;
var buf = StringBuffer('Start: ')
..write('added first, ')
..=> s = toString() // Target is not receiver.
..write('added later, ')
..{ for (var i = 0; i < 2; ++i) write('more, '); } // Statements.
..write('finally at the end!');
// Compare with block form.
buf = StringBuffer('Start: ')..{
write('added first, ');
s = toString();
write('added later, ');
for (var i = 0; i < 2; ++i) write('more, ');
write('finally at the end!');
};
}
// ----------------------------------------------------------------------
// ignore_for_file: unused_local_variable, unused_element
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment