dart-lang / sdk

The Dart SDK, including the VM, dart2js, core libraries, and more.
https://dart.dev
BSD 3-Clause "New" or "Revised" License
9.98k stars 1.54k forks source link

Redefine meaning of "void arrow functions" #33069

Open eernstg opened 6 years ago

eernstg commented 6 years ago

The language team discussed, but did not yet commit to, the following change:

void f() => e; // Static type of `e` can be anything.
// Is syntactic sugar for:
void f() { e; }

g() => e; // Static type of `e` is `void`.
// Is syntactic sugar for:
void g() { e; }

The motivation for the first rule is that it eliminates an inconsistency in the rules: return 42; is an error in a {} function with return type void, based on the consideration that it is too error-prone: It looks like that value is being passed on and used, but that value is actually marked as invalid ("to be discarded") by the return type void.

With the old semantics, void f() => 42; would be allowed, but it would be defined to mean void f() { return 42; } which is not allowed. With the adjustment above it would mean void f() { 42; }, which is allowed.

The motivation for the second rule (g) is that it allows the concise notation using => to create a void function, which is in practice what developers want when they write functions like g() => e; where e has static type void.

We will need a feature specification for this, and the following topics are among the obvious ones that we have not yet considered in detail:


Tasks:

lrhn commented 6 years ago

Also document how this applies to instance methods with a type variable as return type, when the type variable is instantiated with void. (It doesn't, the static type is not void, and the runtime type is Object anyway).

eernstg commented 6 years ago

Yep, rule 1 would apply for a literal void return type, and there is no change to the semantics of a function whose declared return type is a type variable.

Similarly, rule 2 would only apply when the static type of the returned expression is void, and the new semantics does not apply when e has type X which is a type variable, no matter which value X is bound to when the given function is executed.