Open eernstg opened 5 years ago
[This is also re #344]
I'm surprised that nobody mentioned Haskell's $
operator.
f a b c = (((f a) b) c) -- f(a, b, c) in languages without currying like dart
f a $ b c = ((f a) (b c)) -- f(a, b(c))
I'm mentioning this only as an example of a syntactic structure that solves the ambiguity problem. $
is probably not a good token to use in dart.
but curried function invocation would be a radical change for Dart, and simultaneous invocation with multiple arguments in functional languages still require parentheses, because we're passing one value which is a tuple (
f (42, true)
). This seems to indicate that Dart cannot easily use this approach.
Yes. Ruby has optional parentheses and it gets really weird. To avoid some ambiguous cases, the language actually makes a space before (
significant in some places and produces an error when it's omitted. Consider:
sqrt (1 + 2).abs + 3;
sqrt(1 + 2).abs + 3;
I think making parentheses optional is profoundly confusing in a C-derived syntax.
Could
numbers.map(it: it + 2)
be an improvement over
numbers.map((it) => it + 2)
?
EDIT: I talked to Randal Schwartz and he pointed out this syntax is ambiguous with named parameters.
I forget what language it was, but I remember seeing a lambda shorthand that, when there was only one parameter, it allowed forgoing the parameter list entirely by implicitly defining a val
parameter (or something similar):
numbers.map(=> val + 2);
A Dart function invocation requires parentheses, e.g.,
f(42)
. Other languages can be more concise.Functional languages like Haskell and SML use an "empty" operator (a space), e.g.,
f 42
. With curried invocation this extends to several arguments (f 42 true
), but curried function invocation would be a radical change for Dart, and simultaneous invocation with multiple arguments in functional languages still require parentheses, because we're passing one value which is a tuple (f (42, true)
). This seems to indicate that Dart cannot easily use this approach.However, some languages exploit special properties of the declaration (like being the last parameter) and the call site (like passing a function literal, rather than an arbitrary argument), and that allows the concise form using just a space.
For example, a Ruby function invocation can have an 'associated block' which is passed using a mere space (example from Ruby core Array doc):
In the callee, it's possible to test whether such a block was given (
block_given?
) and call it (yield
), but here we are just interested in the fact that we a block is passed at the call site using a concise syntax.Kotlin uses a similar syntax to pass a lambda as the last argument in a function invocation. Here is an example which is at the same time an example of a type-safe builder:
This issue is a request for a similar kind of conciseness in Dart. It may seem like a tiny thing, but it is probably going to be used in a large number of locations.