Last active
November 7, 2025 16:23
-
-
Save eernstg/1310863683c15edf17eb99d06988e646 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 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