Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1003)

Side by Side Diff: CHANGELOG.md

Issue 2648203003: Add 1.22 features to CHANGELOG. (Closed)
Patch Set: Tweak generalized tear-offs. Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 only supported in the VM, and there
9 are almost no known uses of them in the wild.
9 10
10 * The `assert()` statement has been expanded to support an optional second 11 * The `assert()` statement has been expanded to support an optional second
11 `message` argument (SDK issue [27342](https://github.com/dart-lang/sdk/issue s/27342)). 12 `message` argument (SDK issue [27342](https://github.com/dart-lang/sdk/issue s/27342)).
12 13
13 The message is displayed if the assert fails. It can be any object, and it 14 The message is displayed if the assert fails. It can be any object, and it
14 is accessible as `AssertionError.message`. It can be used to provide more 15 is accessible as `AssertionError.message`. It can be used to provide more
15 user friendly exception outputs. As an example, the following assert: 16 user friendly exception outputs. As an example, the following assert:
16 17
17 ```dart 18 ```dart
18 assert(configFile != null, "Tool config missing. Please see https://goo.gl/k 8iAi for details."); 19 assert(configFile != null, "Tool config missing. Please see https://goo.gl/k 8iAi for details.");
19 ``` 20 ```
20 21
21 would produce the following exception output: 22 would produce the following exception output:
22 23
23 ``` 24 ```
24 Unhandled exception: 25 Unhandled exception:
25 'file:///Users/mit/tmp/tool/bin/main.dart': Failed assertion: line 9 pos 10: 26 '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. 27 '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) 28 #0 _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:33)
28 #1 _AssertionError._throwNew (dart:core-patch/errors_patch.dart:29) 29 #1 _AssertionError._throwNew (dart:core-patch/errors_patch.dart:29)
29 #2 main (file:///Users/mit/tmp/tool/bin/main.dart:9:10) 30 #2 main (file:///Users/mit/tmp/tool/bin/main.dart:9:10)
30 ``` 31 ```
31 32
32 * The `Null` type has been moved to the bottom of the type hierarchy. As such, 33 * 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. 34 it is considered a subtype of every other type. The `null` *literal* was
35 always treated as a bottom type. Now the named class `Null` is too:
34 36
35 Examples: 37 ```dart
38 const empty = <Null>[];
39
40 String concatenate(List<String> parts) => parts.join();
41 int sum(List<int> numbers) => numbers.fold(0, (sum, n) => sum + n);
42
43 concatenate(empty); // OK.
44 sum(empty); // OK.
36 ``` 45 ```
37 Null foo() => null;
38 int x = foo();
39 String x = foo();
40 46
41 List<Null> bar() => <Null>[]; 47 * Introduce `covariant` modifier on parameters. It indicates that the
42 List<int> = bar(); 48 parameter (and the corresponding parameter in any method that overrides it)
43 List<String> = bar(); 49 has looser override rules. In strong mode, these require a runtime type
50 check to maintain soundness, but enable an architectural pattern that is
51 useful in some code.
52
53 It lets you specialize a family of classes together, like so:
54
55 ```dart
56 abstract class Predator {
57 void chaseAndEat(covariant Prey p);
58 }
59
60 abstract class Prey {}
61
62 class Mouse extends Prey {}
63
64 class Seal extends Prey {}
65
66 class Cat extends Predator {
67 void chaseAndEat(Mouse m) => ...
68 }
69
70 class Orca extends Predator {
71 void chaseAndEat(Seal s) => ...
72 }
44 ``` 73 ```
45 74
75 This isn't statically safe, because you could do:
76
77 ```dart
78 Predator predator = new Cat(); // Upcast.
79 predator(new Seal()); // Cats can't eat seals!
80 ```
81
82 To preserve soundness in strong mode, in the body of a method that uses a
83 covariant override (here, `Cat.chaseAndEat()`), the compiler automatically
84 inserts a check that the parameter is of the expected type. So the compiler
85 gives you something like:
86
87 ```dart
88 class Cat extends Predator {
89 void chaseAndEat(o) {
90 var m = o as Mouse;
91 ...
92 }
93 }
94 ```
95
96 Spec mode allows this unsound behavior on all parameters, even though users
97 rarely rely on it. Strong mode disallowed it initially. Now, strong mode
98 lets you opt into this behavior in the places where you do want it by using
99 this modifier. Outside of strong mode, the modifier is ignored.
100
101 * Change instantiate-to-bounds rules for generic type parameters when running
102 in strong mode. If you leave off the type parameters from a generic type, we
103 need to decide what to fill them in with. Dart 1.0 says just use `dynamic`,
104 but that isn't sound:
105
106 ```dart
107 class Abser<T extends num> {
108 void absThis(T n) { n.abs(); }
109 }
110
111 var a = new Abser(); // Abser<dynamic>.
112 a.absThis("not a num");
113 ```
114
115 We want the body of `absThis()` to be able to safely assume `n` is at
116 least a `num` -- that's why there's a constraint on T, after all. Implicitly
117 using `dynamic` as the type parameter in this example breaks that.
118
119 Instead, strong mode uses the bound. In the above example, it fills it in
120 with `num`, and then the second line where a string is passed becomes a
121 static error.
122
123 However, there are some cases where it is hard to figure out what that
124 default bound should be:
125
126 ```dart
127 class RuhRoh<T extends Comparable<T>> {}
128 ```
129
130 Strong mode's initial behavior sometimes produced surprising, unintended
131 results. For 1.22, we take a simpler approach and then report an error if
132 a good default type argument can't be found.
133
134 ### Core libraries
135
136 * Define `FutureOr<T>` for code that works with either a future or an
137 immediate value of some type. For example, say you do a lot of text
138 manipulation, and you want a handy function to chain a bunch of them:
139
140 ```dart
141 typedef String StringSwizzler(String input);
142
143 String swizzle(String input, List<StringSwizzler> swizzlers) {
144 var result = input;
145 for (var swizzler in swizzlers) {
146 result = swizzler(result);
147 }
148
149 return result;
150 }
151 ```
152
153 This works fine:
154
155 ```dart
156 main() {
157 var result = swizzle("input", [
158 (s) => s.toUpperCase(),
159 (s) => () => s * 2)
160 ]);
161 print(result); // "INPUTINPUT".
162 }
163 ```
164
165 Later, you realize you'd also like to support swizzlers that are
166 asynchronous (maybe they look up synonyms for words online). You could make
167 your API strictly asynchronous, but then users of simple synchronous
168 swizzlers have to manually wrap the return value in a `Future.value()`.
169 Ideally, your `swizzle()` function would be "polymorphic over asynchrony".
170 It would allow both synchronous and asynchronous swizzlers. Because `await`
171 accepts immediate values, it is easy to implement this dynamically:
172
173 ```dart
174 Future<String> swizzle(String input, List<StringSwizzler> swizzlers) async {
175 var result = input;
176 for (var swizzler in swizzlers) {
177 result = await swizzler(result);
178 }
179
180 return result;
181 }
182
183 main() async {
184 var result = swizzle("input", [
185 (s) => s.toUpperCase(),
186 (s) => new Future.delayed(new Duration(milliseconds: 40), () => s * 2)
187 ]);
188 print(await result);
189 }
190 ```
191
192 What should the declared return type on StringSwizzler be? In the past, you
193 had to use `dynamic` or `Object`, but that doesn't tell the user much. Now,
194 you can do:
195
196 ```dart
197 typedef FutureOr<String> StringSwizzler(String input);
198 ```
199
200 Like the name implies, `FutureOr<String>` is a union type. It can be a
201 `String` or a `Future<String>`, but not anything else. In this case, that's
202 not super useful beyond just stating a more precise type for readers of the
203 code. It does give you a little better error checking in code that uses the
204 result of that.
205
206 `FutureOr<T>` becomes really important in *generic* methods like
207 `Future.then()`. In those cases, having the type system understand this
208 magical union type helps type inference figure out the type argument of
209 `then()` based on the closure you pass it.
210
211 Previously, strong mode had hard-coded rules for handling `Future.then()`
212 specifically. `FutureOr<T>` exposes that functionality so third-party APIs
213 can take advantage of it too.
214
46 ### Tool changes 215 ### Tool changes
47 216
48 * Dart2Js 217 * Dart2Js
49 218
50 * Remove support for (long-time deprecated) mixin typedefs. 219 * Remove support for (long-time deprecated) mixin typedefs.
51 220
52 * Pub 221 * Pub
53 222
54 * Avoid using a barback asset server for executables unless they actually use 223 * Avoid using a barback asset server for executables unless they actually use
55 transformers. This makes precompilation substantially faster, produces 224 transformers. This makes precompilation substantially faster, produces
(...skipping 1433 matching lines...) Expand 10 before | Expand all | Expand 10 after
1489 they will keep the Dart process alive until they time out. This fixes the 1658 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 1659 handling of persistent connections. Previously, the client would shut down
1491 immediately after a request. 1660 immediately after a request.
1492 1661
1493 * **Breaking change:** `HttpServer` no longer compresses all traffic by 1662 * **Breaking change:** `HttpServer` no longer compresses all traffic by
1494 default. The new `autoCompress` property can be set to `true` to re-enable 1663 default. The new `autoCompress` property can be set to `true` to re-enable
1495 compression. 1664 compression.
1496 1665
1497 * `dart:isolate`: `Isolate.spawnUri` added the optional `packageRoot` argument, 1666 * `dart:isolate`: `Isolate.spawnUri` added the optional `packageRoot` argument,
1498 which controls how it resolves `package:` URIs. 1667 which controls how it resolves `package:` URIs.
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698