Google Groups

Re: [misc] “Missing” language features: varargs and multistatement lambdas

Bob Nystrom Jan 31, 2012 10:44 AM
Posted in group: Dart Misc
On Tue, Jan 31, 2012 at 5:55 AM, flying sheep <> wrote:
i thought about the syntax and found some (imho) oddities:

1. varargs:

it’s no problem to define a constructor to accept an optional List
argument, i know, but defining your own “literals” has its own charm
and is less tedious and more DRY.

instead of new Set.from(['x', 'y']), new Set('1', '2', '3') could be

We had varargs (or "rest params" in the lingua of other languages) in Dart for a while. It is handy in a few places (along with its buddy the spread operator). However, function parameter lists are already one of the most intricate corners of the language. In a very small chunk of the grammar, we need to worry about positional parameters, named optional parameters (which may be called by name or position), field initializer parameters, and noSuchMethod's generic support for working with argument lists.

Cramming rest params in there too is pretty hard. (Imagine defining a function that has both optional and rest params and try to figure out what gets bound to what. Now imagine compiling that to JS. Now imagine compiling it to JS and needing to support noSuchMethod).

To keep things as simple as possible at least for now we took them out. They can always return later on once we've got the existing features nice and baked.

2. multistatement lambdas

scala does function definitions like that: for functions without
return value, you type def <name> <block>, for functions with one, you
type def <name> = <statement|block>

you have to use block braces for the first one, but can leave them out
for the second (for e.g. getters).

Yes, we have that in Dart too: both single expression lambdas and multiple statement function expressions. Both, of course, have full access to their lexical closure.
in functions returning something,
the return value of the last statement in the control flow is returned
if it is reached, but you can also break out of the control flow by
using the return keyword. i think it’s nice and functional.

Right, this is the piece we don't have. Scala, like most functional languages, doesn't have statements. Everything is an expression, including block bodies. What looks like a statement block is an expression containing a series of expressions. Its result is the result of the last expression. (In other words, it's like the comma operator in C.)

I really like languages that work that way (which includes CoffeeScript, Scala, Ruby, and most languages derived from Lisp or ML). However, most people aren't familiar with expression-oriented languages. C and its derivatives all have a strong statement/expression distinction and that's the most popular paradigm in languages today. Dart follows closely in those footsteps.

In practice, you don't lose that much by having statements: you've got to do an explicit return at the end of some blocks, and you have to use a ternary operator instead of if being an expression.

i’s most likely too late to change it, but designating at the
beginning if a function returns something (different than null) and
then returning the last value is better than the C(++) way.

It may be better from the expressiveness angle but it's less familiar to lots of programmers and unfamiliarity is a tax we're always cautious about having to pay.

what do you think? will “=>” be viewed like python’s lambda in the
future (useful sometimes, but never fully thought through)?

No, I don't think so. For what it's worth, I think Python does the right thing here too. Significant indentation doesn't play nice with nested expressions, which is what you'd be talking about with multiline lambdas there. CoffeeScript does this and I find that corner of its syntax pretty hairy.


- bob