-
Notifications
You must be signed in to change notification settings - Fork 205
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Requst: Optional parentheses for one argument arrow function #320
Comments
I think this can be made into a fairly safe syntax change. It likely won't affect readability, the Without parentheses, there is no way to specify an argument type, so it will only work where the argument type is inferred (so it has to be equivalent to Would we want to allow zero-parameter functions like Would we want it to work for block bodies too? I fear that we might end up with style guides requiring or disallowing the parentheses when they are no necessary. If you change |
I think we should reserve it for the latter. |
This is related to #265 which is about eliminating the argument entirely when there is exactly one required argument. We could then write Zero-argument functions would still have to be written explicitly, but that's already a bit shorter than a one-argument function (so the motivation for abbreviating it is less compelling). |
I think that's probably the wrong default. Many closures want to access the original surrounding method's somethings.forEach((foo) => methodOnThis(foo, 3)); It would be nice to be able to shorten it to, say: somethings.forEach(=> methodOnThis(it, 3)); |
[Edit May 28th 2019: A custom binding of @munificent wrote:
Right, the updated proposal #265 only supports the form that you prefer: somethings.forEach(=> methodOnThis(it, 3)); |
Can we go one step further and drop that ugly arrow also? If it has no left-hand side, it does not make sense to keep it. |
If we drop the arrow, what's left is just the expression. How then would we tell that it is intended as the body of a function, and not as an expression which evaluates to a function? |
If |
Probably not enough. There needs to be some delimiter. T id<T>(T x) =>x;
List<int Function(int)> fns = ...;
... fns.map(id)... // means what? If we can omit the arrow and variable name, the syntax can no longer distinguish between the meanings that are currently written: Both are type-valid today. |
I'm not sure I understand the problem...
T id<T>(T x) => x;
T power<T>(T x) => x * x;
List<int Function(int)> fns = ...;
... fns.map(id)... // Means the same as today
... fns.map(power)... // Means the same as today
... fns.map(it)... // The `it` expressions means `(it) => it`, and is unambiguous
... fns.map(it * it)... // As `it` is used, this means `(it) => it * it` |
How deep can it contain Take: var x = foos.addAll(bar.map(it+1)); Is this var x = foos.addAll((it) => bar.map(it+1)); or var x = foos.addAll(bar.map((it) => it+1)); Or, heck, var x = (it) => foos.addAll(bar.map(it+1)); It looks "easy" here because I use recognizable names that you might think you know the meaning of, but compilers don't recognize names as having meaning. It just looks at syntax. If we say "innermost possible expression", then that's ... always radixes.forEach(print(number.toString(radix:it))); I guess "innermost argument expression which isn't radixes.forEach(print((it) => number.toString(radix:it))); which doesn't work. One can then say "can't use shorthand for that, have to be explicit", and that'll probably work, but also make refactoring harder. Say you start with extension on String {
void printToLog() {
log.print(this);
}
}
/// ...
foos.forEach(it.toString().printToLog()); Then you inline the foos.forEach(log.print(it.toString())); ... which does not work, because I think it will be too chaotic without some textual delimiter saying where a new function body starts, because without that, everything looks like expressions, and expressions can occur anywhere already. |
Yeah, not that I prefer omitting completely the arrow. Actually, I usually prefer more explicit approaches, I was just brainstorming. I didn't think about nesting, and although it is indeed solvable I think it would actually generate more confusion, as there would be a lot of "subrules" that the user would have to know in order do properly use I agree that the arrow is ugly, tho, haha |
One mayor difference. in the first case In kotlin you have, for the first concern, Do not complicate things. If you want to change the syntax to that form, those |
Arrow functions, or lambdas as some languages call it, are frequently used in dart, even more so in the Flutter framework. Most of these arrow functions only contain one argument. At the language's current standing, if I were to write a
forEach
loop on a List, I would have to do something like this:forEach
is just one of the many places that an arrow function is frequently used.As you can see, the parentheses around the
item
make the whole arrow function a little awkward to write and also read. I propose the following change: make the parenthensis around one argument arrow functions optional, permitting writing code as such:This makes the code much cleaner to read and to write.
The text was updated successfully, but these errors were encountered: