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

Side by Side Diff: src/site/articles/m1-language-changes/index.markdown

Issue 10788006: new site (Closed) Base URL: https://code.google.com/p/dartlang-site/@master
Patch Set: final patch Created 8 years, 5 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
OLDNEW
1 --- 1 ---
2 layout: default 2 layout: default
3 title: "Milestone 1 Language Changes" 3 title: "Milestone 1 Language Changes"
4 rel: 4 rel:
5 author: bob-nystrom 5 author: bob-nystrom
6 description: "A brief introduction to some of the language changes we are making heading into our next milestone." 6 description: "A brief introduction to some of the language changes planned for t he M1 milestone."
7 --- 7 ---
8 8
9 # Milestone 1 Language Changes 9 # Milestone 1 Language Changes
10 10
11 Right now as we near our Milestone 1 release, we are making a slew of fun lang uage changes. There are tracking bugs in the repo for all of them, but I wanted to run through them here and try to provide some context and rationale where I c an. 11 Right now as we near our "Milestone 1" release, we are making a slew of fun lang uage changes. There are tracking bugs in the repo for all of them, but I wanted to run through them here and try to provide some context and rationale where I c an.
12 12
13 ## Contents 13 ## Contents
14 14
15 1. [First class types](#first-class-types) 15 1. [First class types](#first-class-types)
16 1. [No explicit interfaces](#no-explicit-interfaces) 16 1. [No explicit interfaces](#no-explicit-interfaces)
17 1. [No "+" on String](#no--on-string) 17 1. [No "+" on String](#no--on-string)
18 1. [No throwing `null`](#no-throwing-null) 18 1. [No throwing `null`](#no-throwing-null)
19 1. [The as cast operator](#the-as-cast-operator) 19 1. [The "as" cast operator](#the-as-cast-operator)
20 1. [Cascades](#cascades) 20 1. [Cascades](#cascades)
21 1. [Lazy static initialization](#lazy-static-initialization) 21 1. [Lazy static initialization](#lazy-static-initialization)
22 1. [Support const modifier for variables](#support-const-modifier-for-variable s) 22 1. [Support "const" modifier for variables](#support-const-modifier-for-variable s)
23 1. [Syntax for defining operators](#syntax-for-defining-operators) 23 1. [Syntax for defining operators](#syntax-for-defining-operators)
24 1. [Split library scope and import scope](#split-library-scope-and-import-scope) 24 1. [Split library scope and import scope](#split-library-scope-and-import-scope)
25 1. [Revised switch](#revised-switch) 25 1. [Revised switch](#revised-switch)
26 1. [Selective imports](#selective-imports) 26 1. [Selective imports](#selective-imports)
27 1. [Re-export](#re-export) 27 1. [Re-export](#re-export)
28 1. [Static methods are constants](#static-methods-are-constants) 28 1. [Static methods are constants](#static-methods-are-constants)
29 1. [New catch syntax](#new-catch-syntax) 29 1. [New catch syntax](#new-catch-syntax)
30 1. [Getter and setter definition syntax](#getter-and-setter-definition-syntax) 30 1. [Getter and setter definition syntax](#getter-and-setter-definition-syntax)
31 1. [Conclusion](#conclusion) 31 1. [Conclusion](#conclusion)
32 {:.toc} 32 {:.toc}
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 {% endhighlight %} 78 {% endhighlight %}
79 79
80 Note that it says *implements*, not *extends*. We are not subclassing Person, we are just saying that Imposter supports all of the public methods Person defines and that we can pass it to anything that expects a Person. 80 Note that it says *implements*, not *extends*. We are not subclassing Person, we are just saying that Imposter supports all of the public methods Person defines and that we can pass it to anything that expects a Person.
81 81
82 Dart also supports abstract methods in classes. Given abstract methods and impli cit interfaces, there’s no actual need for an explicit interface construct: just make a class where all of its methods are abstract, and then implement its impl icit interface. 82 Dart also supports abstract methods in classes. Given abstract methods and impli cit interfaces, there’s no actual need for an explicit interface construct: just make a class where all of its methods are abstract, and then implement its impl icit interface.
83 83
84 Getting rid of interfaces simplifies the language while also removing some of th e limitations that interfaces had: unlike classes, they couldn’t define static m embers for example. It also simplifies designing an API: you no longer have thin k about whether you should define something as an interface or an abstract class . 84 Getting rid of interfaces simplifies the language while also removing some of th e limitations that interfaces had: unlike classes, they couldn’t define static m embers for example. It also simplifies designing an API: you no longer have thin k about whether you should define something as an interface or an abstract class .
85 85
86 ## No "+" on String 86 ## No "+" on String
87 87
88 A deeply contentious issue, Dart no longer allows using the “+” operator on stri ngs. So no more: 88 A deeply contentious issue, Dart no longer allows using the "+" operator on stri ngs. So no more:
89 89
90 {% highlight dart %} 90 {% highlight dart %}
91 print("Hi, " + yourName); 91 print("Hi, " + yourName);
92 {% endhighlight %} 92 {% endhighlight %}
93 93
94 There seem to be as many reasons for (and against) this change as there are Dart team members, but the two motivators I see repeatedly are: 94 There seem to be as many reasons for (and against) this change as there are Dart team members, but the two motivators I see repeatedly are:
95 95
96 1. It’s a source of bugs and surprising behavior because it’s not symmetric and is sensitive to operator precedence. `print("1 + 2 = " + 1 + 2)` doesn’t do what some people might expect and `"a" + 1` and `1 + "a"` have unpleasantly differen t behavior. 96 1. It’s a source of bugs and surprising behavior because it’s not symmetric and is sensitive to operator precedence. `print("1 + 2 = " + 1 + 2)` doesn’t do what some people might expect and `"a" + 1` and `1 + "a"` have unpleasantly differen t behavior.
97 97
98 2. Naïve code that uses it heavily can have poor performance with simple interna l string implementations. If you do something like use `+=` in a loop to build u p a long string, and you’re running on an implementation that doesn’t have sophi sticated code for handling strings you can end up doing a lot of wasted allocati ons. 98 2. Naïve code that uses it heavily can have poor performance with simple interna l string implementations. If you do something like use `+=` in a loop to build u p a long string, and you’re running on an implementation that doesn’t have sophi sticated code for handling strings you can end up doing a lot of wasted allocati ons.
99 99
100 So, without `+`, what should you do when you need to staple a couple of strings to each other? Fortunately, [Seth has your back here](http://news.dartlang.org/2 012/06/vm-to-remove-support-for-string.html). 100 So, without `+`, what should you do when you need to staple a couple of strings to each other? Fortunately, [Seth has your back here](http://news.dartlang.org/2 012/06/vm-to-remove-support-for-string.html).
101 101
102 ([Tracking issue #3707](http://dartbug.com/3707)) 102 ([Tracking issue #3707](http://dartbug.com/3707))
103 103
104 ## No throwing `null` 104 ## No throwing `null`
105 105
106 Dart now considers it a dynamic error to throw `null`. In almost every case wher e `null` is thrown, it’s a programmer error: they meant to throw some exception object but accidentally got a `null` instead. By disallowing this, we can detect that error earlier and help the user fix their code. 106 Dart now considers it a dynamic error to throw `null`. In almost every case wher e `null` is thrown, it’s a programmer error: they meant to throw some exception object but accidentally got a `null` instead. By disallowing this, we can detect that error earlier and help the user fix their code.
107 107
108 *Allowing* `null` to be thrown, on the other hand, forces programmers to think a bout what kinds of `catch` clauses will match it. Will a `catch` clause of any t ype select `null`? None of them? Just `var ex`? There isn’t an obvious intuitive correct behavior here, so users are likely to be confused. 108 *Allowing* `null` to be thrown, on the other hand, forces programmers to think a bout what kinds of `catch` clauses will match it. Will a `catch` clause of any t ype select `null`? None of them? Just `var ex`? There isn’t an obvious intuitive correct behavior here, so users are likely to be confused.
109 109
110 ([Tracking issue #2940](http://dartbug.com/2940)) 110 ([Tracking issue #2940](http://dartbug.com/2940))
111 111
112 ## The as cast operator 112 ## The "as" cast operator
113 113
114 Dart now has an infix operator `as` that lets you cast an expression to a given type without having to declare a type annotated local variable. Where before, if you wanted to indicate some extra knowledge about the types of objects in your code, you had to do: 114 Dart now has an infix operator `as` that lets you cast an expression to a given type without having to declare a type annotated local variable. Where before, if you wanted to indicate some extra knowledge about the types of objects in your code, you had to do:
115 115
116 {% highlight dart %} 116 {% highlight dart %}
117 ButtonElement button = query('button'); 117 ButtonElement button = query('button');
118 button.value = 1234; 118 button.value = 1234;
119 {% endhighlight %} 119 {% endhighlight %}
120 120
121 Now you can do: 121 Now you can do:
122 122
(...skipping 19 matching lines...) Expand all
142 142
143 or the tedium of having to define a local variable: 143 or the tedium of having to define a local variable:
144 144
145 {% highlight dart %} 145 {% highlight dart %}
146 var toggleButton = query('#my-form').query('button'); 146 var toggleButton = query('#my-form').query('button');
147 toggleButton.classes.add('toggle'); 147 toggleButton.classes.add('toggle');
148 toggleButton.text = 'Click Me!'; 148 toggleButton.text = 'Click Me!';
149 toggleButton.labels.add(toggleLabel); 149 toggleButton.labels.add(toggleLabel);
150 {% endhighlight %} 150 {% endhighlight %}
151 151
152 Some APIs, like jQuery in JavaScript or StringBuffer in Java get around this by using fluent interfaces: their methods return this so you can chain calls dire ctly. But that forces API designers to choose between returning a useful value o r allowing chaining: they can’t support both. It also forces all APIs to be desi gned up front to support this. 152 Some APIs, like jQuery in JavaScript or StringBuffer in Java get around this by using "fluent interfaces": their methods return this so you can chain calls dire ctly. But that forces API designers to choose between returning a useful value o r allowing chaining: they can’t support both. It also forces all APIs to be desi gned up front to support this.
153 153
154 To remedy that, Smalltalk pioneered something called message cascades which Da rt has adopted. These let you sequence a series of method calls that all apply t o the same receiver, like so: 154 To remedy that, Smalltalk pioneered something called "message cascades" which Da rt has adopted. These let you sequence a series of method calls that all apply t o the same receiver, like so:
155 155
156 {% highlight dart %} 156 {% highlight dart %}
157 query('#my-form').query('button') 157 query('#my-form').query('button')
158 ..classes.add('toggle') 158 ..classes.add('toggle')
159 ..text = 'Click Me!' 159 ..text = 'Click Me!'
160 ..labels.add(toggleLabel); 160 ..labels.add(toggleLabel);
161 {% endhighlight %} 161 {% endhighlight %}
162 162
163 Here, everything after `..` is called on the result of the expression before the first `..`. What’s nice is that this works with every API, not just ones explic itly implemented using a fluent pattern. 163 Here, everything after `..` is called on the result of the expression before the first `..`. What’s nice is that this works with every API, not just ones explic itly implemented using a fluent pattern.
164 164
165 ([Tracking issue #2501](http://dartbug.com/2501)) 165 ([Tracking issue #2501](http://dartbug.com/2501))
166 166
167 ## Lazy static initialization 167 ## Lazy static initialization
168 168
169 Formerly, Dart required that all `static final` fields (or `final` top-level var iables) be initialized with constant expressions. In other words, they could onl y be used to define compile-time constants. That significantly limits their use, preventing, for example, this field: 169 Formerly, Dart required that all `static final` fields (or `final` top-level var iables) be initialized with constant expressions. In other words, they could onl y be used to define compile-time constants. That significantly limits their use, preventing, for example, this field:
170 170
171 {% highlight dart %} 171 {% highlight dart %}
172 class Stopwatch { 172 class Stopwatch {
173 static final startTime = new DateTime.now(); 173 static final startTime = new DateTime.now();
174 } 174 }
175 {% endhighlight %} 175 {% endhighlight %}
176 176
177 We’ve decided to loosen that so that `static final` fields and `final` top-level variables can be initialized using *any* expression. These will then be lazy in itialized the first time the variable is accessed. This is closer to behavior us ers coming from Java or C# expect given Dart’s similar syntax. 177 We’ve decided to loosen that so that `static final` fields and `final` top-level variables can be initialized using *any* expression. These will then be lazy in itialized the first time the variable is accessed. This is closer to behavior us ers coming from Java or C# expect given Dart’s similar syntax.
178 178
179 ([Tracking issue #3557](http://dartbug.com/3557)) 179 ([Tracking issue #3557](http://dartbug.com/3557))
180 180
181 ## Support const modifier for variables 181 ## Support "const" modifier for variables
182 182
183 The above change is more flexible, but it leaves an open issue: how do you defin e a `static final` field or `final` top-level variable that *is* constant, and t hat can be used in constant expressions? With this looser behavior, you lose the ability to do: 183 The above change is more flexible, but it leaves an open issue: how do you defin e a `static final` field or `final` top-level variable that *is* constant, and t hat can be used in constant expressions? With this looser behavior, you lose the ability to do:
184 184
185 {% highlight dart %} 185 {% highlight dart %}
186 class SomeClass { 186 class SomeClass {
187 static final someConstant = 123; 187 static final someConstant = 123;
188 static final aConstList = const [someConstant]; 188 static final aConstList = const [someConstant];
189 } 189 }
190 {% endhighlight %} 190 {% endhighlight %}
191 191
192 Since `someConstant` doesn’t *have* to be constant now, it may not be, which mea ns it can’t be used in a constant expression like `const [someConstant]`. To fix that, Dart will also allow `const` as a modifier for variables. This way you ca n indicate which top-level `final` variables and `static final` fields are const ant and which are lazy-initialized non-constant: 192 Since `someConstant` doesn’t *have* to be constant now, it may not be, which mea ns it can’t be used in a constant expression like `const [someConstant]`. To fix that, Dart will also allow `const` as a modifier for variables. This way you ca n indicate which top-level `final` variables and `static final` fields are const ant and which are lazy-initialized non-constant:
193 193
194 {% highlight dart %} 194 {% highlight dart %}
195 class SomeClass { 195 class SomeClass {
196 static const someConstant = 123; // OK 196 static const someConstant = 123; // OK
197 static final startTime = new DateTime.now(); // OK too 197 static final startTime = new DateTime.now(); // OK too
198 static const aConstList = const [someConstant]; // also OK 198 static const aConstList = const [someConstant]; // also OK
199 } 199 }
200 {% endhighlight %} 200 {% endhighlight %}
201 201
202 ([Tracking issue #3549](http://dartbug.com/3549)) 202 ([Tracking issue #3549](http://dartbug.com/3549))
203 203
204 ## Syntax for defining operators 204 ## Syntax for defining operators
205 205
206 This is a pretty minor change. The previous spec used `equals` and `negate` as s pecial identifiers for defining equality and unary negation operators, respectiv ely. That raises some confusing questions like Can you also call those methods by name? To simplify that, we will just use `==` and `-` to define those operat ors. We’ll disambiguate unary and binary minus by their arity (number of paramet ers). 206 This is a pretty minor change. The previous spec used `equals` and `negate` as s pecial identifiers for defining equality and unary negation operators, respectiv ely. That raises some confusing questions like "Can you also call those methods by name?" To simplify that, we will just use `==` and `-` to define those operat ors. We’ll disambiguate unary and binary minus by their arity (number of paramet ers).
207 207
208 {% highlight dart %} 208 {% highlight dart %}
209 class MagicNumber { 209 class MagicNumber {
210 bool operator ==(other) => … 210 bool operator ==(other) => …
211 MagicNumber operator -() => … // unary negate 211 MagicNumber operator -() => … // unary negate
212 MagicNumber operator -(other) => … // infix minus 212 MagicNumber operator -(other) => … // infix minus
213 } 213 }
214 {% endhighlight %} 214 {% endhighlight %}
215 215
216 ([Tracking issue #3765](http://dartbug.com/3765)) 216 ([Tracking issue #3765](http://dartbug.com/3765))
217 217
218 ## Split library scope and import scope 218 ## Split library scope and import scope
219 219
220 Stephen [explains the rationale for this change](http://code.google.com/p/dart/i ssues/detail?id=1285) better than I can: 220 Stephen [explains the rationale for this change](http://code.google.com/p/dart/i ssues/detail?id=1285) better than I can:
221 221
222 > There is a problem that a name may be defined by `#import` or by a definition in the current library. A change to the imported library can break a program by introducing a clashing name. 222 > There is a problem that a name may be defined by `#import` or by a definition in the current library. A change to the imported library can break a program by introducing a clashing name.
223 223
224 What he means here is consider you have this program: 224 What he means here is consider you have this program:
225 225
226 {% highlight dart %} 226 {% highlight dart %}
227 #import('somelib.dart'); 227 #import('somelib.dart');
228 228
229 foo() => print('foo!'); 229 foo() => print('foo!');
230 main() => foo(); 230 main() => foo();
231 {% endhighlight %} 231 {% endhighlight %}
232 232
233 Later, you upgrade to the latest greatest version of somelib and discover to y our dismay that they’ve added a `foo()` function to it. Currently, this breaks y our code since those names are in the same namespace and collide. Stephen’s prop osal is: 233 Later, you upgrade to the latest greatest version of "somelib" and discover to y our dismay that they’ve added a `foo()` function to it. Currently, this breaks y our code since those names are in the same namespace and collide. Stephen’s prop osal is:
234 234
235 > I suggest that imports happen into a scope surrounding the current library. T his would reduce a clash in an imported library to an override warning and at th e same time ensure the current library's behaviour did not change. 235 > I suggest that imports happen into a scope surrounding the current library. T his would reduce a clash in an imported library to an override warning and at th e same time ensure the current library's behaviour did not change.
236 236
237 In other words, with this change, your local `foo()` will *shadow* the new one i n somelib instead of colliding, and your code does the right thing. 237 In other words, with this change, your local `foo()` will *shadow* the new one i n "somelib" instead of colliding, and your code does the right thing.
238 238
239 In addition, we’ve removed another annoying restriction. Previously, if you impo rted the same name from two different libraries (say Node from dart:html and dar tdoc) then you would get a name collision error *even if you didn’t use that nam e anywhere in your code.* Now, Dart will only worry about name collisions for na mes that you actually use. You only get an error if there is an ambiguous *use* of a name in your code. 239 In addition, we’ve removed another annoying restriction. Previously, if you impo rted the same name from two different libraries (say Node from dart:html and dar tdoc) then you would get a name collision error *even if you didn’t use that nam e anywhere in your code.* Now, Dart will only worry about name collisions for na mes that you actually use. You only get an error if there is an ambiguous *use* of a name in your code.
240 240
241 ([Tracking issue #1285](http://dartbug.com/1285)) 241 ([Tracking issue #1285](http://dartbug.com/1285))
242 242
243 ## Revised switch 243 ## Revised switch
244 244
245 In its original incarnation, Dart’s `switch` statement worked like JavaScript’s and not Java’s. It was essentially syntactic sugar for a series of chained `if-e lse` statments. For example, this: 245 In its original incarnation, Dart’s `switch` statement worked like JavaScript’s and not Java’s. It was essentially syntactic sugar for a series of chained `if-e lse` statments. For example, this:
246 246
247 {% highlight dart %} 247 {% highlight dart %}
(...skipping 14 matching lines...) Expand all
262 hasBeard = true; 262 hasBeard = true;
263 } else { 263 } else {
264 hasBeard = false; 264 hasBeard = false;
265 } 265 }
266 {% endhighlight %} 266 {% endhighlight %}
267 267
268 Note that in the desugared `if-else` form, it ends up calling the equality (`==` ) operator. This operator can be overloaded for your own types, so this has an i mportant consequence. With these semantics, a `switch` statement *must* be handl ed exactly like a series of chained `if-else` statements. 268 Note that in the desugared `if-else` form, it ends up calling the equality (`==` ) operator. This operator can be overloaded for your own types, so this has an i mportant consequence. With these semantics, a `switch` statement *must* be handl ed exactly like a series of chained `if-else` statements.
269 269
270 This has unpleasant optimization implications. In languages like C and Java, a ` switch` statement can only be used with numeric values. Compilers can and do com pile down a `switch` statement to either a jump table that directly selects a ca se based on the value, or to a binary search of the cases, or some mixed heurist ic of the two. In other words, in those languages selecting the right `case` for a `switch` can have `O(1)` or `O(log n)` performance (where `n` is the number o f cases). In Dart, it’s always `O(n)`. 270 This has unpleasant optimization implications. In languages like C and Java, a ` switch` statement can only be used with numeric values. Compilers can and do com pile down a `switch` statement to either a jump table that directly selects a ca se based on the value, or to a binary search of the cases, or some mixed heurist ic of the two. In other words, in those languages selecting the right `case` for a `switch` can have `O(1)` or `O(log n)` performance (where `n` is the number o f cases). In Dart, it’s always `O(n)`.
271 271
272 So we’ve decided to restrict `switch` in Dart. Instead of calling a user-defined equality operator, we only allow you to switch on numbers, strings, and constan t objects. This gives compilers enough flexibility to compile them more efficien tly. Since constant objects are canonicalized, they can be reliably compared pur ely based on *identity*, so they don’t have the problem of allowing user-defined equality operators. This lets you still switch on user-defined enum-like obje cts. 272 So we’ve decided to restrict `switch` in Dart. Instead of calling a user-defined equality operator, we only allow you to switch on numbers, strings, and constan t objects. This gives compilers enough flexibility to compile them more efficien tly. Since constant objects are canonicalized, they can be reliably compared pur ely based on *identity*, so they don’t have the problem of allowing user-defined equality operators. This lets you still switch on user-defined "enum-like" obje cts.
273 273
274 ## Selective imports 274 ## Selective imports
275 275
276 Library imports were a blunt instrument in Dart: you either imported every singl e name from a library or none of them. If a single name in that library collides with another one you’re importing, your only recourse is to import that entire library with a prefix. 276 Library imports were a blunt instrument in Dart: you either imported every singl e name from a library or none of them. If a single name in that library collides with another one you’re importing, your only recourse is to import that entire library with a prefix.
277 277
278 Now, you’ll be given finer grained control. If you do: 278 Now, you’ll be given finer grained control. If you do:
279 279
280 {% highlight dart %} 280 {% highlight dart %}
281 #import('somelib.dart', show: ['foo', 'bar']); 281 #import('somelib.dart', show: ['foo', 'bar']);
282 {% endhighlight %} 282 {% endhighlight %}
283 283
284 Then you will *only* import the names foo and bar from somelib. This is go od if you are only using a small part of a library and want to make that clear. Conversely: 284 Then you will *only* import the names "foo" and "bar" from "somelib". This is go od if you are only using a small part of a library and want to make that clear. Conversely:
285 285
286 {% highlight dart %} 286 {% highlight dart %}
287 #import('somelib.dart', hide: ['foo', 'bar']); 287 #import('somelib.dart', hide: ['foo', 'bar']);
288 {% endhighlight %} 288 {% endhighlight %}
289 289
290 Here, you import every name except foo and bar. This is good for excluding t he one name that happens to cause a collision. 290 Here, you import every name except "foo" and "bar". This is good for excluding t he one name that happens to cause a collision.
291 291
292 ([Tracking issue #817](http://dartbug.com/817)) 292 ([Tracking issue #817](http://dartbug.com/817))
293 293
294 ## Re-export 294 ## Re-export
295 295
296 Let’s say you’re doing some refactoring and you decide to move a class from one library to another. But, you don’t want to break all of the code that assumes th at class is still in the old library. Ideally, you’d like code that imports *eit her* of those to be able to get to your class: you want it to appear to be in bo th places. 296 Let’s say you’re doing some refactoring and you decide to move a class from one library to another. But, you don’t want to break all of the code that assumes th at class is still in the old library. Ideally, you’d like code that imports *eit her* of those to be able to get to your class: you want it to appear to be in bo th places.
297 297
298 Or, let’s say you have a giant library with hundreds of names in it (we’ll call it dart:html). You want to split that up into a few smaller libraries. But you ’d also like users that want the whole kit and caboodle to just be able to impor t dart:html and get everything. 298 Or, let’s say you have a giant library with hundreds of names in it (we’ll call it "dart:html"). You want to split that up into a few smaller libraries. But you ’d also like users that want the whole kit and caboodle to just be able to impor t "dart:html" and get everything.
299 299
300 To fix this, Dart has re-exports. When you import a library, you can choose to also re-export the names you import from it. That will make it appear to code u sing *your* library that those names are coming directly from it. This lets you decouple the library where users get something from the library where it’s physi cally defined. For example: 300 To fix this, Dart has "re-exports". When you import a library, you can choose to also re-export the names you import from it. That will make it appear to code u sing *your* library that those names are coming directly from it. This lets you decouple the library where users get something from the library where it’s physi cally defined. For example:
301 301
302 {% highlight dart %} 302 {% highlight dart %}
303 // bar.dart 303 // bar.dart
304 someMethod() => print('hi!'); 304 someMethod() => print('hi!');
305 anotherMethod() => print('hello!'); 305 anotherMethod() => print('hello!');
306 306
307 // foo.dart 307 // foo.dart
308 #import('bar.dart', export: true); 308 #import('bar.dart', export: true);
309 {% endhighlight %} 309 {% endhighlight %}
310 310
311 Thanks to the `export: true` part here, any code that imports foo.dart will be able to access `someMethod()` and `anotherMethod()` as if they had been defined directly in foo.dart. You can use this in combination with selective imports to only re-export a subset of the names that an imported library defines. If we change the import in foo.dart to: 311 Thanks to the `export: true` part here, any code that imports "foo.dart" will be able to access `someMethod()` and `anotherMethod()` as if they had been defined directly in "foo.dart". You can use this in combination with selective imports to only re-export a subset of the names that an imported library defines. If we change the import in "foo.dart" to:
312 312
313 {% highlight dart %} 313 {% highlight dart %}
314 #import('bar.dart', show: ['someMethod'], export: true); 314 #import('bar.dart', show: ['someMethod'], export: true);
315 {% endhighlight %} 315 {% endhighlight %}
316 316
317 Then only `someMethod` will be re-exported. 317 Then only `someMethod` will be re-exported.
318 318
319 ([Tracking issue #760](http://dartbug.com/760)) 319 ([Tracking issue #760](http://dartbug.com/760))
320 320
321 ## Static methods are constants 321 ## Static methods are constants
(...skipping 13 matching lines...) Expand all
335 const Logger(this.logCallback(arg)); 335 const Logger(this.logCallback(arg));
336 } 336 }
337 {% endhighlight %} 337 {% endhighlight %}
338 338
339 ([Tracking issue #1652](http://dartbug.com/1652)) 339 ([Tracking issue #1652](http://dartbug.com/1652))
340 340
341 ## New catch syntax 341 ## New catch syntax
342 342
343 One strange consequence of marrying Dart’s optional type semantics with a Java-l ike syntax is that you end up with a syntax for `catch` clauses that *looks* lik e a type annotation, but is very much not like a type annotation in Dart: Dart t ype annotations have no runtime effects, but the type in a `catch` clause is use d at runtime to test against the thrown exception. 343 One strange consequence of marrying Dart’s optional type semantics with a Java-l ike syntax is that you end up with a syntax for `catch` clauses that *looks* lik e a type annotation, but is very much not like a type annotation in Dart: Dart t ype annotations have no runtime effects, but the type in a `catch` clause is use d at runtime to test against the thrown exception.
344 344
345 This causes some confusion and some nasty syntactic corner cases. For example, i f you just have `catch(foo)` does that mean catch an exception of any type and bind it to `foo` (which lines up with other parameters in Dart where the type a nnotation is optional), or does it mean catch an exception of type `foo` and do n’t bind it to a variable (which is what it would mean in Java)? 345 This causes some confusion and some nasty syntactic corner cases. For example, i f you just have `catch(foo)` does that mean "catch an exception of any type and bind it to `foo`" (which lines up with other parameters in Dart where the type a nnotation is optional), or does it mean "catch an exception of type `foo` and do n’t bind it to a variable" (which is what it would mean in Java)?
346 346
347 To avoid that, we decided that that syntax is invalid and you *must* do either ` catch(var foo)` or `catch(foo someVar)` to be clear about your intent. But that’ s definitely *not* the syntax for a parameter in Dart, so now users trip over *t hat.* 347 To avoid that, we decided that that syntax is invalid and you *must* do either ` catch(var foo)` or `catch(foo someVar)` to be clear about your intent. But that’ s definitely *not* the syntax for a parameter in Dart, so now users trip over *t hat.*
348 348
349 Our fix is to not try to follow Java-style syntax for this at all. Instead, Dart does: 349 Our fix is to not try to follow Java-style syntax for this at all. Instead, Dart does:
350 350
351 {% highlight dart %} 351 {% highlight dart %}
352 try { 352 try {
353 ... 353 ...
354 } on SomeException catch(ex) { ... } 354 } on SomeException catch(ex) { ... }
355 {% endhighlight %} 355 {% endhighlight %}
(...skipping 11 matching lines...) Expand all
367 {% endhighlight %} 367 {% endhighlight %}
368 368
369 This makes the syntax for defining them closer to how they are invoked. (You ca n of course have a curly block body too in addition to the simple lambda body sh own above.) 369 This makes the syntax for defining them closer to how they are invoked. (You ca n of course have a curly block body too in addition to the simple lambda body sh own above.)
370 370
371 Setters now have an `=` after their name, before the parameter list: 371 Setters now have an `=` after their name, before the parameter list:
372 372
373 {% highlight dart %} 373 {% highlight dart %}
374 set theAnswer=(int value) { print('The answer is now $value.'); } 374 set theAnswer=(int value) { print('The answer is now $value.'); }
375 {% endhighlight %} 375 {% endhighlight %}
376 376
377 When reflecting over a type (in the forthcoming mirrors system), the name of a s etter will include the “=”, so this makes the definition syntax reflect that. 377 When reflecting over a type (in the forthcoming mirrors system), the name of a s etter will include the "=", so this makes the definition syntax reflect that.
378 378
379 ([Tracking issue #3602](http://dartbug.com/3602)) 379 ([Tracking issue #3602](http://dartbug.com/3602))
380 380
381 ## Conclusion 381 ## Conclusion
382 382
383 There are a few other minor changes and clean-ups, but that’s the big noticeable stuff. As always, your feedback, questions and comments are welcome on the [mai ling list](http://dartlang.org/mailing-list) and our [issue tracker](http://dart bug.com). 383 There are a few other minor changes and clean-ups, but that’s the big noticeable stuff. As always, your feedback, questions and comments are welcome on the [mai ling list](http://dartlang.org/mailing-list) and our [issue tracker](http://dart bug.com).
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698