Index: docs/newsletter/20170804.md |
diff --git a/docs/newsletter/20170804.md b/docs/newsletter/20170804.md |
new file mode 100644 |
index 0000000000000000000000000000000000000000..79ecebd6305fc851b25d7588d337abae4c1ca26a |
--- /dev/null |
+++ b/docs/newsletter/20170804.md |
@@ -0,0 +1,120 @@ |
+# Dart Language and Library Newsletter |
+2017-08-04 |
+@floitschG |
+ |
+Welcome to the Dart Language and Library Newsletter. |
+ |
+## Under Active Development |
+This section provides updates to the areas we are actively working on. Many of these sections have a more detailed explanation in a previous newsletter. |
+ |
+### Better Organization |
+Goal: collect and organize the documents (proposals, ...) the Dart language team produces. |
+ |
+We are storing all interesting proposals in `docs/language/informal` (in the [Dart repository](http://github.com/dart-lang/sdk)). |
+ |
+For example, there is a proposal for asserts in initializer lists [assert_init]. This feature allows to write basic assertions in the initializer list. The main use-case is for `const` constructors, which are not allowed to have bodies. |
+ |
+For example: |
+``` dart |
+class A { |
+ final int y; |
+ const A(int x) : assert(x < 10), y = x + 1; |
+} |
+``` |
+ |
+I will cover some of the proposals in future newsletters. Feel free to send me requests for specific proposals in that directory. |
+ |
+[assert_init]: https://github.com/dart-lang/sdk/blob/master/docs/language/informal/assert-in-initializer-list.md |
+ |
+### Void as a Type |
+Goal: allow `void` as a type. In particular, make it possible to use it in generics, such as `Future<void>`. |
+ |
+Erik (@eernstg) wrote a first proposal for an informal spec, and we are actively discussing his proposal now. I'm in the process of writing an easily digestible document on this feature (hopefully for the next newsletter), but you can also read Erik's (more formal) proposal here: |
+https://gist.github.com/eernstg/7d79ef7f3e56daf5ce1b7e57684b18c6 |
+ |
+We hope to add this proposal to our documentation directory, soon. |
+ |
+### Updates to the Core Libraries |
+Goal: clean up the core libraries. Deprecate rarely used classes/methods and add missing functionality. |
+ |
+Small progress: we wrote CLs (but haven't submitted them yet) for deprecating `SplayTreeMap`, `SplayTreeSet` and `DoubleLinkedList`. These classes (and their tests) are migrated to `package:collection`. The core SDK has been updated to not use any of these classes anymore. |
+ |
+While we haven't finalized the list of core library changes, here are a few more likely candidates: |
+* add `map` to `Map`: `Iterable<T> map<T>(T Function(K, V) f)`. This function makes it possible to iterate over all key-value pairs (similar to `Map.forEach`) and build a new iterable out of them. |
+* add `followedBy` to `Iterable`: `Iterable<T> followedBy(Iterable<T> other)`. With this method, it is finally possible to concatenate two iterables. This makes the unintuitive `[iterable1, iterable2].expand((x) => x)` pattern obsolete: `iterable1.followedBy(iterable2)`. |
+* add `+` to `List`: concatenates two lists: `List<T> operator +(List<T> other)`. Contrary to `followedBy` (which is inherited from `Iterable`), using `+` to concatenate two lists produces a list that is eagerly constructed. Example: `[1, 2] + [3, 4] // -> [1, 2, 3, 4]`. |
+ |
+These changes are more breaking than the ones we mentioned last week. We don't know yet how and when we want to land them to avoid the least amount of disruption. |
+ |
+ |
+## Deferred Loading |
+The current spec does not allow types to be used across deferred library imports. This makes sense, when the deferred sources are not known. This means that users currently have to introduce interfaces for classes that could just be referenced directly. |
+ |
+``` dart |
+// lib1.dart |
+abstract class InterfaceA { |
+ foo(); |
+} |
+// lib2.dart |
+import 'lib1.dart'; |
+class A implements InterfaceA { |
+ foo() => 499; |
+} |
+// lib3.dart |
+import 'lib1.dart'; |
+import 'lib2.dart' deferred as def; |
+ |
+main() { |
+ InterfaceA a; |
+ def.loadLibrary().then((_) => a = new def.A()); |
+} |
+``` |
+ |
+Since dart2js and DDC actually know all the sources during compilation, this boilerplate code feels painful. We are thus looking into alternatives. |
+ |
+We discussed one proposal that suggested to remove deferred loading from the language entirely and leave it up to the compilers (DDC and dart2js primarily) to deal with deferred loading. Instead of language syntax, the compilers would have used annotations and specially recognized functions to effectively have the same semantics as the current specification. They could then evolve from there to provide a better experience. |
+ |
+Here is an example, of how this would look like: |
+ |
+``` dart |
+import "package:deferred/deferred.dart" show deferred, loadLibrary; |
+ |
+@Deferred("lib1") |
+import "lib1.dart" as lib1; |
+ |
+void main() { |
+ // loadLibrary is specially recognized by dart2js. |
+ loadLibrary(const Deferred("lib1")).then((_) { |
+ /* Assume lib1 has been loaded. */ |
+ print(new lib1.A()); |
+ }); |
+} |
+``` |
+ |
+Since the language doesn't provide any guidance, DDC and dart2js could then implement their own restrictions (potentially using more annotations). |
+ |
+We have discarded this idea, because (among other reasons) the language front-end is too much involved in deferred loading. For example, it needs to keep track which types are referenced through (deferred) prefixes. If the front-end needs to be involved in such a high degree, then we should specify what exactly it needs to do. |
+ |
+Our plan is now to allow uses of deferred types even when the deferred libraries haven't been loaded yet. This means that sources of deferred libraries must be available during compilation of non-deferred functions: |
+ |
+``` 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`. |
+} |
+``` |
+ |
+While this change is clearly breaking (and we know of a few programs that created the deferred libraries in the main library), in practice, deferred loading is mainly used as a deployment tool to cut down the size of the initial payload. At that time all sources are available. |
+ |
+The main tool that is affected by the new semantics is dart2js. We are tracking work on this feature in dart2js here: https://github.com/dart-lang/sdk/issues/29903 |
+ |
+Once dart2js has the resources to implement and experiment with the new semantics we will provide updates. |