# Dart Language and Library Newsletter
2017-08-11
@floitschG

Welcome to the Dart Language and Library Newsletter.

## Follow Ups

### Void Arrow Functions
As mentioned in an earlier newsletter, `void` arrow functions with non-void expressions (as in `void foo() => x++`) are supported with Dart 1.24. However, this feature still has to be used with care. Due to a temporary limitation of the type inference in strong mode, returning a non-void expression might not work as expected.

For example:

``` dart
var f = new Future(() { doSomethingAsynchronously(); };
f.catchError((e) => errorCounter++);
```

The type-inference algorithm currently infers `Null` for the generic type of the `Future`. Functions without `return` indeed return `null`, so technically, that type is correct. However, the `catchError` signature requires the provided function to return the same type as the function it is attached to. In this case, `f` is a `Future<Null>`, but `errorCounter++` is an `int`. Since `int` is not `Null` this throws at runtime.

As mentioned in earlier newsletters, we are actively working on generalizing `void`, and once it is supported the inferred type of `f` will be `Future<void>`. The `catchError` closure then would just need to be a subtype of `void Function()` which would work fine for `(e) => errorCounter++`. Until then, be careful where you use the `void` arrow function syntax.

### Deferred Loading
Last time we discussed our plans to allow the use of deferred types even when the deferred libraries haven't been loaded yet. This makes programs, like the following, possible:

``` dart
/// lib1.dart
class A {}

/// lib2.dart
export "lib1.dart" show A;

/// main.dart
import "lib1.dart";
import "lib2.dart" deferred as def;

main() {
  print(new A() is def.A);  // Requires knowledge of `def.A`.
}
```

A follow-up mail questioned the need for such a big hammer. In reality, most programs just want to use the deferred type as a type annotations:

``` dart
main() async {
  def.A a; // <-- Illegal today.
  await def.loadLibrary();
  a = new def.A();
}
```

Is there a simpler / better solution that would allow patterns like these, but not require full knowledge of the deferred types?

It turns out, that the answer is likely "no". In fact, we find that, because of type inference, even the current behavior is already counterintuitive and should be fixed. That is, even without allowing more uses of deferred types, programs don't behave as expected:

``` dart
// ------ def.dart
class Box<T> {
  T value;
  Box(this.value);
}

// ------ main.dart
import "def.dart" deferred as def;

main() async {
  await def.loadLibrary();
  var box = new def.Box(499);
  var list = [box.value];
}
```

With type inference, users expect three things to happen:
1. `box` is of type `def.Box<int>`.
2. the generic type of `new def.Box(499)` is `Box<int>`, as if the user had written `new def.Box<int>(499)`.
3. `list` is of type `List<int>`.

Without access to the deferred sources, none of these expectations is met. Since type inference runs at compile-time, `box` has to be treated like `dynamic`. There is simply not more information available. For similar reasons, `box` must be of type `Box<dynamic>`. Since the invocation of the constructor happens at runtime (where no type-inference happens), the missing generic type is dynamically filled with `dynamic`.

Finally, `list` must be of type `List<dynamic>` since `box.value` is a dynamic invocation, and the type inference doesn't know that the returned value will be of type `int`.

This small example shows that type inference requires knowledge of the deferred types to do its job. This means that all sources must be available when compiling individual libraries. Once that's the case it doesn't make sense to restrict the use of deferred types. They don't take up much space (which is the usual reason for deferring libraries), and giving full access to them removes a lot of boilerplate or dynamic code.

## Const Functions
The language team discussed the possibility of supporting `const` functions.

``` dart
class A {
  final Function(e) callback;
  const A(this.callback);
}

// Provide a `const` function to `A`'s constructor.
const x = const A(const (e) { print(e); });

// Default values have to be `const`.
void sort(List<int> list, [int compare(int x, int y) = const (x, y) => x - y) {
  ...
}
```

This feature doesn't add new functionality. Users can already now write a static function with the same body and use its tear-off (which is guaranteed to be `const`) in all of these locations. However, it's more convenient to write functions closer to where they are needed. For example, the classic `map.putIfAbsent(x, () => [])` allocates a new function (a cheap operation, but still), whereas `map.putIfAbsent(x, const () => [])` would always reuse the same function.

Sidenote: in dart2js, many const values (not functions) are allocated at initialization, which shifts some execution time to the beginning of the program where many teams already struggle with performance. In the current dart2js version it's thus not always beneficial to make objects `const`.

## Shadowing of Core Libraries
When deprecating core library classes (like `SplayTreeMap`) we intend to minimize the cost to our users. We copy the deprecated classes to packages (in this case `collection`) so that users just need to change their imports from `dart:collection` to `package:collection`. However, that means that programs that import `dart:collection` and `package:collection` at the same time now see the same class twice; once from each import. Which class should Dart now use? Is this an error?

For "normal" imports (not `dart:`), the rules are simple: an ambiguous reference is an error. There is no good way to decide between class `A` of package `pkg1` or `pkg2`. With core libraries, things get a bit more complicated: whereas upgrading packages is a user-triggered action (with the fallback to revert to the previous `pubspec.lock`), upgrading the SDK should generally be safe. As a consequence, Dart considers core libraries as less important. That is, shadowing a class from any `dart:` library is ok. Importing `dart:collection` and `package:collection/collection.dart` is thus fine and will not lead to errors. It's still good practice to use `show` and `hide` to make the intention completely clear.

We are still unsure how to handle cases when the user explicitly used `show` to import a specific core library type:

``` dart
import 'dart:collection' show SplayTreeMap;
import 'package:collection/collection.dart';
```

