Index: CHANGELOG.md |
diff --git a/CHANGELOG.md b/CHANGELOG.md |
index b59769d32455c12691d59eca5a517bf821264727..775bcbb86a330c9dd6d751e553d7e6df7fe6dfc9 100644 |
--- a/CHANGELOG.md |
+++ b/CHANGELOG.md |
@@ -33,7 +33,8 @@ |
it is considered a subtype of every other type. |
eernst
2017/01/24 09:13:50
We could add the following sentence here, to addre
Bob Nystrom
2017/01/26 21:20:31
Done.
|
Examples: |
eernst
2017/01/24 09:13:51
And then we might as well delete this line.
Bob Nystrom
2017/01/26 21:20:30
Done. Also came up with a more motivating example.
|
- ``` |
+ |
+ ```dart |
Null foo() => null; |
int x = foo(); |
String x = foo(); |
@@ -43,6 +44,125 @@ |
List<String> = bar(); |
``` |
+ * Introduce `covariant` modifier on parameters. Adding that indicates that the |
Lasse Reichstein Nielsen
2017/01/24 06:52:40
Please say very early that this is only intended f
eernst
2017/01/24 09:13:51
+1!
So at this point we could have 'Support the `
mit
2017/01/24 14:55:01
+1 for having a `### Language (strong mode only)`
Bob Nystrom
2017/01/26 21:20:31
That would be tricky because then we'd still have
|
+ parameter (and the corresponding parameter in any method that overrides it) |
+ has looser override rules which require a runtime type check to maintain |
+ soundness, but enable an architectural pattern that is useful in some code. |
+ |
+ It lets you specialize a family of classes together, like so: |
+ |
+ ```dart |
+ abstract class Predator { |
+ void chaseAndEat(covariant Prey p); |
+ } |
+ |
+ abstract class Prey {} |
+ |
+ class Cat extends Predator { |
+ void chaseAndEat(Mouse m) => ... |
+ } |
+ |
+ class Mouse extends Prey {} |
+ |
+ // Eaten by orcas. |
eernst
2017/01/24 09:13:51
Ought to add 'class Orca extends Predator ..', and
Bob Nystrom
2017/01/26 21:20:31
Done.
|
+ class Seal extends Prey {} |
+ ``` |
+ |
+ This isn't statically safe, because you could do: |
+ |
+ ```dart |
+ Predator predator = new Cat(); // Upcast. |
+ predator(new Seal()); // Cats can't eat seals! |
+ ``` |
+ |
+ To preserve soundness, in the body of a method that uses a covariant |
+ override (here, `Cat.chaseAndEat()`), the compiler automatically inserts |
+ a check that the parameter is of the expected type. So the compiler gives |
+ you something like: |
+ |
+ ```dart |
+ class Cat extends Predator { |
+ void chaseAndEat(o) { |
+ var m = o as Mouse; |
+ ... |
+ } |
+ } |
+ ``` |
+ |
+ Dart 1.0 allows this unsound behavior on all parameters, even though users |
+ rarely rely on it. Strong mode disallowed it initially. Now it lets you |
+ opt into in the places where you do want it using this modifier. |
eernst
2017/01/24 09:13:51
'opt into [it]..', or maybe just 'it lets you use
Bob Nystrom
2017/01/26 21:20:31
Done.
|
+ |
+ * Change instantiate-to-bounds rules for generic type parameters. If you leave |
Leaf
2017/01/24 07:55:27
"for generic type parameters when running in stron
eernst
2017/01/24 09:13:51
With a separate section for strong mode, this shou
Bob Nystrom
2017/01/26 21:20:31
Done.
|
+ off the type parameters from a generic type, we need to decide what to fill |
+ them in with. Dart 1.0 says just use `dynamic`, but that isn't sound: |
+ |
+ ```dart |
+ class Abser<T extends num> { |
+ void absThis(T n) { n.abs(); } |
+ } |
+ |
+ var a = new Abser(); // A<dynamic>. |
eernst
2017/01/24 09:13:51
'// Abser<dynamic>', presumably.
Bob Nystrom
2017/01/26 21:20:31
Done.
|
+ a.absThis("not a num"); |
+ ``` |
+ |
+ We want the body of `absThis()` to be able to safely assume `n` is at |
+ least a `num` -- that's why there's a constraint on T, after all. Implicitly |
+ using `dynamic` as the type parameter in this example breaks that. |
+ |
+ Instead, strong mode uses the bound. In the above example, it fills it in |
+ with `num`, and then the second line where a string is passed becomes a |
+ static error. |
+ |
+ However, there are some cases where it is hard to figure out what that |
+ default bound should be: |
+ |
+ ```dart |
+ class RuhRoh<T extends Comparable<T>> {} |
+ ``` |
+ |
+ Strong mode's initial behavior sometimes produced surprising, unintended |
+ results. For 1.22, we take a simpler approach and then report an error if |
+ a good default type argument can't be found. |
+ |
+### Core libraries |
+ |
+ * Define `FutureOr<T>` for code that works with either a future or an |
+ immediate value of some type. Some APIs are "polymorphic over asynchrony". |
+ For example, say you have some interface for doing manipulations on text: |
+ |
+ ```dart |
+ abstract class StringSwizzler { |
+ ??? swizzle(String input); |
+ } |
+ ``` |
Lasse Reichstein Nielsen
2017/01/24 06:52:40
Please, please, please do not use this example. Th
Leaf
2017/01/24 07:55:27
+1 Future.value, Future.then are both good example
Bob Nystrom
2017/01/26 21:20:31
Came up with a different example. I do think the o
|
+ |
+ Users can implement this to do their own string manipulations. You'd like |
+ users to be able to write `swizzle()` methods that are synchronous or |
+ asynchronous. Either is fine. (Barback transformers are a concrete example |
+ of this.) What is the return type of this method? |
Lasse Reichstein Nielsen
2017/01/24 06:52:40
Again, not a choice that I recommend. I'd probably
Bob Nystrom
2017/01/26 21:20:31
Yup, fair point. Came up with a better example.
|
+ |
+ Now, it would be: |
+ |
+ ```dart |
+ abstract class StringSwizzler { |
+ FutureOr<String> swizzle(String input); |
+ } |
+ ``` |
+ |
+ In this case, that's not super useful beyond just stating a more precise |
+ type for readers of the code. It does give you a little better error |
+ checking in code that uses the result of that. |
+ |
+ But this becomes really important in generic methods like `Future.then()` |
+ where you take a callback whose return type is `FutureOr<T>`. In those |
+ cases, having the type system understand this magical union type gives you |
+ much better type inference for the type argument of the method. |
+ |
+ Previously, strong mode had hard-coded rules for handling `Future.then()` |
+ specifically. `FutureOr<T>` exposes that functionality so third-party APIs |
+ can take advantage of it. |
+ |
### Tool changes |
* Dart2Js |