OLD | NEW |
---|---|
1 ## 1.22.0 | 1 ## 1.22.0 |
2 | 2 |
3 ### Language | 3 ### Language |
4 | 4 |
5 * Breaking change: ['Generalized tear-offs'](https://github.com/gbracha/genera lizedTearOffs/blob/master/proposal.md) | 5 * Breaking change: ['Generalized tear-offs'](https://github.com/gbracha/genera lizedTearOffs/blob/master/proposal.md) |
6 are no longer supported, and will cause errors. We updated the language spec | 6 are no longer supported, and will cause errors. We updated the language spec |
7 and added warnings in 1.21, and are now taking the last step to fully | 7 and added warnings in 1.21, and are now taking the last step to fully |
8 de-support them. They were previously supported in the VM only. | 8 de-support them. They were previously supported in the VM only. |
9 | 9 |
10 * The `assert()` statement has been expanded to support an optional second | 10 * The `assert()` statement has been expanded to support an optional second |
(...skipping 12 matching lines...) Expand all Loading... | |
23 ``` | 23 ``` |
24 Unhandled exception: | 24 Unhandled exception: |
25 'file:///Users/mit/tmp/tool/bin/main.dart': Failed assertion: line 9 pos 10: | 25 'file:///Users/mit/tmp/tool/bin/main.dart': Failed assertion: line 9 pos 10: |
26 'configFile != null': Tool config missing. Please see https://goo.gl/k8iAi f or details. | 26 'configFile != null': Tool config missing. Please see https://goo.gl/k8iAi f or details. |
27 #0 _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:33) | 27 #0 _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:33) |
28 #1 _AssertionError._throwNew (dart:core-patch/errors_patch.dart:29) | 28 #1 _AssertionError._throwNew (dart:core-patch/errors_patch.dart:29) |
29 #2 main (file:///Users/mit/tmp/tool/bin/main.dart:9:10) | 29 #2 main (file:///Users/mit/tmp/tool/bin/main.dart:9:10) |
30 ``` | 30 ``` |
31 | 31 |
32 * The `Null` type has been moved to the bottom of the type hierarchy. As such, | 32 * The `Null` type has been moved to the bottom of the type hierarchy. As such, |
33 it is considered a subtype of every other type. | 33 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.
| |
34 | 34 |
35 Examples: | 35 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.
| |
36 ``` | 36 |
37 ```dart | |
37 Null foo() => null; | 38 Null foo() => null; |
38 int x = foo(); | 39 int x = foo(); |
39 String x = foo(); | 40 String x = foo(); |
40 | 41 |
41 List<Null> bar() => <Null>[]; | 42 List<Null> bar() => <Null>[]; |
42 List<int> = bar(); | 43 List<int> = bar(); |
43 List<String> = bar(); | 44 List<String> = bar(); |
44 ``` | 45 ``` |
45 | 46 |
47 * 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
| |
48 parameter (and the corresponding parameter in any method that overrides it) | |
49 has looser override rules which require a runtime type check to maintain | |
50 soundness, but enable an architectural pattern that is useful in some code. | |
51 | |
52 It lets you specialize a family of classes together, like so: | |
53 | |
54 ```dart | |
55 abstract class Predator { | |
56 void chaseAndEat(covariant Prey p); | |
57 } | |
58 | |
59 abstract class Prey {} | |
60 | |
61 class Cat extends Predator { | |
62 void chaseAndEat(Mouse m) => ... | |
63 } | |
64 | |
65 class Mouse extends Prey {} | |
66 | |
67 // 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.
| |
68 class Seal extends Prey {} | |
69 ``` | |
70 | |
71 This isn't statically safe, because you could do: | |
72 | |
73 ```dart | |
74 Predator predator = new Cat(); // Upcast. | |
75 predator(new Seal()); // Cats can't eat seals! | |
76 ``` | |
77 | |
78 To preserve soundness, in the body of a method that uses a covariant | |
79 override (here, `Cat.chaseAndEat()`), the compiler automatically inserts | |
80 a check that the parameter is of the expected type. So the compiler gives | |
81 you something like: | |
82 | |
83 ```dart | |
84 class Cat extends Predator { | |
85 void chaseAndEat(o) { | |
86 var m = o as Mouse; | |
87 ... | |
88 } | |
89 } | |
90 ``` | |
91 | |
92 Dart 1.0 allows this unsound behavior on all parameters, even though users | |
93 rarely rely on it. Strong mode disallowed it initially. Now it lets you | |
94 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.
| |
95 | |
96 * 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.
| |
97 off the type parameters from a generic type, we need to decide what to fill | |
98 them in with. Dart 1.0 says just use `dynamic`, but that isn't sound: | |
99 | |
100 ```dart | |
101 class Abser<T extends num> { | |
102 void absThis(T n) { n.abs(); } | |
103 } | |
104 | |
105 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.
| |
106 a.absThis("not a num"); | |
107 ``` | |
108 | |
109 We want the body of `absThis()` to be able to safely assume `n` is at | |
110 least a `num` -- that's why there's a constraint on T, after all. Implicitly | |
111 using `dynamic` as the type parameter in this example breaks that. | |
112 | |
113 Instead, strong mode uses the bound. In the above example, it fills it in | |
114 with `num`, and then the second line where a string is passed becomes a | |
115 static error. | |
116 | |
117 However, there are some cases where it is hard to figure out what that | |
118 default bound should be: | |
119 | |
120 ```dart | |
121 class RuhRoh<T extends Comparable<T>> {} | |
122 ``` | |
123 | |
124 Strong mode's initial behavior sometimes produced surprising, unintended | |
125 results. For 1.22, we take a simpler approach and then report an error if | |
126 a good default type argument can't be found. | |
127 | |
128 ### Core libraries | |
129 | |
130 * Define `FutureOr<T>` for code that works with either a future or an | |
131 immediate value of some type. Some APIs are "polymorphic over asynchrony". | |
132 For example, say you have some interface for doing manipulations on text: | |
133 | |
134 ```dart | |
135 abstract class StringSwizzler { | |
136 ??? swizzle(String input); | |
137 } | |
138 ``` | |
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
| |
139 | |
140 Users can implement this to do their own string manipulations. You'd like | |
141 users to be able to write `swizzle()` methods that are synchronous or | |
142 asynchronous. Either is fine. (Barback transformers are a concrete example | |
143 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.
| |
144 | |
145 Now, it would be: | |
146 | |
147 ```dart | |
148 abstract class StringSwizzler { | |
149 FutureOr<String> swizzle(String input); | |
150 } | |
151 ``` | |
152 | |
153 In this case, that's not super useful beyond just stating a more precise | |
154 type for readers of the code. It does give you a little better error | |
155 checking in code that uses the result of that. | |
156 | |
157 But this becomes really important in generic methods like `Future.then()` | |
158 where you take a callback whose return type is `FutureOr<T>`. In those | |
159 cases, having the type system understand this magical union type gives you | |
160 much better type inference for the type argument of the method. | |
161 | |
162 Previously, strong mode had hard-coded rules for handling `Future.then()` | |
163 specifically. `FutureOr<T>` exposes that functionality so third-party APIs | |
164 can take advantage of it. | |
165 | |
46 ### Tool changes | 166 ### Tool changes |
47 | 167 |
48 * Dart2Js | 168 * Dart2Js |
49 | 169 |
50 * Remove support for (long-time deprecated) mixin typedefs. | 170 * Remove support for (long-time deprecated) mixin typedefs. |
51 | 171 |
52 * Pub | 172 * Pub |
53 | 173 |
54 * Avoid using a barback asset server for executables unless they actually use | 174 * Avoid using a barback asset server for executables unless they actually use |
55 transformers. This makes precompilation substantially faster, produces | 175 transformers. This makes precompilation substantially faster, produces |
(...skipping 1433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1489 they will keep the Dart process alive until they time out. This fixes the | 1609 they will keep the Dart process alive until they time out. This fixes the |
1490 handling of persistent connections. Previously, the client would shut down | 1610 handling of persistent connections. Previously, the client would shut down |
1491 immediately after a request. | 1611 immediately after a request. |
1492 | 1612 |
1493 * **Breaking change:** `HttpServer` no longer compresses all traffic by | 1613 * **Breaking change:** `HttpServer` no longer compresses all traffic by |
1494 default. The new `autoCompress` property can be set to `true` to re-enable | 1614 default. The new `autoCompress` property can be set to `true` to re-enable |
1495 compression. | 1615 compression. |
1496 | 1616 |
1497 * `dart:isolate`: `Isolate.spawnUri` added the optional `packageRoot` argument, | 1617 * `dart:isolate`: `Isolate.spawnUri` added the optional `packageRoot` argument, |
1498 which controls how it resolves `package:` URIs. | 1618 which controls how it resolves `package:` URIs. |
OLD | NEW |