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

Side by Side Diff: CHANGELOG.md

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