A few times in my project, I wanted to make a cascading list that ends with a final member accession. For example
class BinaryBuilder { ... }
```dart
var bytes = BinaryBuilder()
..writeInteger(1)
..writeInteger(2)
..writeInteger(3)
.done();
However, due to the order of operations, I must do this:
```dart
var bytes = (BinaryBuilder()
..writeInteger(1)
..writeInteger(2)
..writeInteger(3))
.done();
* Note the extra parentheses before BinaryBuilder() and after ..writeInteger(3)
EDIT: Here is an example with official code using args
final args = (ArgParser()
..addFlag("verbose", abbr: "v"))
.parse(arguments);
While this can be annoying, changing the precedence order would make it impossible to do more than call one method in a cascade.
Currently you can do:
something
..getSomeThings().forEach(print)
..getOtherThings().map((x) => x.toString()).forEach(print)
Each cascade section can be a chain of operations.
If we make the change you suggest, then that would becomes impossible, while the operation you want to do is currently possible by adding parentheses.
We'd have to introduce a new syntax for the composite cascade operations, maybe something like:
something
..(getSomeThings().forEach(print))
..(getOtherThings().map((x) => x.toString()).forEach(print))
```
So, avoiding parentheses in one place means introducing parentheses in another place.
On the other hand, those other parentheses might be useful for other things as well, like nested cascades:
```dart
foo
..(bar..baz()..qux())
..fifi()
That's currently not possible at all because the nested cascade would bind to foo not foo.bar.
If anything, I'd rather have a cascade-end operator (or a more general precedence override operator) so you could write:
var bytes = BinaryBuilder()
..writeInteger(1)
..writeInteger(2)
..writeInteger(3):
.done();
The : (which is probably not a good choice of syntax) would end the previous expression, and avoid the .done binding to that. I guess you could use more :s to move the binding even further out.
It's acting like a postfix "end parentheses with implicit start parentheses", putting the start parenthesis at the latest position where it would be valid and would make a difference.
Not sure the Dart syntax would really work well with such an operator, though.
All in all, simply changing the current syntax to allow only single methods in cascades won't happen. It breaks existing code with no migration path. We will need to add something more to make that code work again, and then we will probably do something completely different.
I agree with @lrhn. I'm going to close this out since changing operator precedence would be massively breaking and deeply confusing. (Consider that it means basically every existing blog post and StackOverflow answer extant on the web would become wrong.)
Most helpful comment
While this can be annoying, changing the precedence order would make it impossible to do more than call one method in a cascade.
Currently you can do:
Each cascade section can be a chain of operations.
If we make the change you suggest, then that would becomes impossible, while the operation you want to do is currently possible by adding parentheses.
We'd have to introduce a new syntax for the composite cascade operations, maybe something like:
That's currently not possible at all because the nested cascade would bind to
foonotfoo.bar.If anything, I'd rather have a cascade-end operator (or a more general precedence override operator) so you could write:
The
:(which is probably not a good choice of syntax) would end the previous expression, and avoid the.donebinding to that. I guess you could use more:s to move the binding even further out.It's acting like a postfix "end parentheses with implicit start parentheses", putting the start parenthesis at the latest position where it would be valid and would make a difference.
Not sure the Dart syntax would really work well with such an operator, though.
All in all, simply changing the current syntax to allow only single methods in cascades won't happen. It breaks existing code with no migration path. We will need to add something more to make that code work again, and then we will probably do something completely different.