4 new changes to the Dart language spec
The Dart team published version 0.08 of the Dart language spec, including 15 changes. I've detailed four of the most exciting changes below, some of which you might have seen as early proposals. Not all of these changes are implemented yet, but they show what direction the language and team is moving.
Previously, static class variables and top level variables had to be compile time constants. This kept initialization costs at startup low, but otherwise was constraining to the developer. With this change, static class variables and top level variables will be initialized at first access (lazily) and no longer need to constant. This is a developer friendly change that keeps initialization costs low.
Version 0.08 of the spec now reads "Static variable declarations are initialized lazily. The first time a static variable v is read, it is set to the result of evaluating its initializer."
For example, this will soon be possible:
This feature is not yet implemented (as of 2012-03-25).
In my opinion, equality in Dart just got a lot more simple. With the new changes, equality of the form a == b works like this:
Lazily Initialization for static variables
This change was proposed in February 2012.Previously, static class variables and top level variables had to be compile time constants. This kept initialization costs at startup low, but otherwise was constraining to the developer. With this change, static class variables and top level variables will be initialized at first access (lazily) and no longer need to constant. This is a developer friendly change that keeps initialization costs low.
Version 0.08 of the spec now reads "Static variable declarations are initialized lazily. The first time a static variable v is read, it is set to the result of evaluating its initializer."
For example, this will soon be possible:
class Awesome {
static PonyPower ponyPower = new PonyPower();
}
class PonyPower {
// NOT a const constructor
PonyPower() {
// feed and groom pony
}
activate() {
// summon rainbow
}
}
main() {
var power = Awesome.ponyPower; // initializes ponyPower now
power.activate();
}
static PonyPower ponyPower = new PonyPower();
}
class PonyPower {
// NOT a const constructor
PonyPower() {
// feed and groom pony
}
activate() {
// summon rainbow
}
}
main() {
var power = Awesome.ponyPower; // initializes ponyPower now
power.activate();
}
This feature is not yet implemented (as of 2012-03-25).
New equality semantics
This change was proposed in January 2012, and with version 0.08 of the spec, it finally gets added to the language.In my opinion, equality in Dart just got a lot more simple. With the new changes, equality of the form a == b works like this:
- If a === b (is same instance), return true. Otherwise,
- If either a or b is null, return false. Otherwise,
- return the result of a.equals(b)
You are free to implement .equals() in your class to further define equality semantics. The rules imply you no longer need to check for === or null in your .equals() method.
This feature is not yet implemented (as of 2012-03-25).
Cascaded method invocations
This change was proposed in February 2012. Also, this particular feature should be considered less stable than the others.
Cascades allow you to chain numerous method calls to the same object, even if the API wasn't originally designed for that.
For example, consider the case of using the HTML5 Canvas API. Before the cascade feature, you would have to write the following code:
ctx.beginPath();
ctx.fillStyle = penColor;
ctx.arc(tx, ty, penWidth/2+2, 0, PI2, true);
ctx.fill();
ctx.moveTo(wx, wy);
ctx.strokeStyle = "black";
ctx.lineTo(tx, ty);
ctx.closePath();
ctx.stroke();
With cascades, this gets simplified and less redundant with:
ctx
..beginPath()
..fillStyle = penColor
..arc(tx, ty, penWidth/2+2, 0, PI2, true)
..fill()
..moveTo(wx, wy)
..strokeStyle = "black"
..lineTo(tx, ty)
..closePath()
..stroke();
The treatment for a cascade, which is object..method, is essentially like writing:
(x){x.method; return x;}(object)
In other words, "create a function, pass in some object x, call the method on x, and return x".
Note that array and map calls also work with cascades, as a cascade can work with any method, operator, setter, or getter.
This feature is not yet implemented (as of 2012-03-25).
Having + to concatenate Strings leads to puzzlers, and we're taking advantage of building a new language by taking this opportunity to remove some of the subtle "features" that have lead to known puzzlers in the past.
Before you cry out in angst, allow me to show you how to deal with Strings, including a new feature that came in to compensate for removing +.
Remember that Dart has String interpolation, which can lead to code like this:
Also, Dart has multi-line Strings thanks to triple quotes:
For the hat trick, Dart now also has adjacent String literals:
Both the Dart VM and the Dart to JavaScript compiler already support adjacent string literals, so we encourage you to remove all uses of + for string concatenation, as + on String will be removed soon.
In this post, I covered lazy initialization for statics, new equality semantics, cascaded method invocations, and removal of the + operator for string concatenation.
As always, the Dart team wants you to join the discussion. Please join the mailing list or enter feature requests and bug reports to dartbug.com. A good way to get early notification of some language changes is to follow the Dart News and Updates feed.
(x){x.method; return x;}(object)
In other words, "create a function, pass in some object x, call the method on x, and return x".
Note that array and map calls also work with cascades, as a cascade can work with any method, operator, setter, or getter.
This feature is not yet implemented (as of 2012-03-25).
Removal of String + concatenation
This change we've been warning about for a while.Having + to concatenate Strings leads to puzzlers, and we're taking advantage of building a new language by taking this opportunity to remove some of the subtle "features" that have lead to known puzzlers in the past.
Before you cry out in angst, allow me to show you how to deal with Strings, including a new feature that came in to compensate for removing +.
Remember that Dart has String interpolation, which can lead to code like this:
var name = 'Bob';
var msg = 'Hello, $name.';
var msg = 'Hello, $name.';
Also, Dart has multi-line Strings thanks to triple quotes:
var html = """
<tr>
<td>Snake Eyes</td>
<td>Storm Shadow</td>
<td>Firefly</td>
</tr>""";
<tr>
<td>Snake Eyes</td>
<td>Storm Shadow</td>
<td>Firefly</td>
</tr>""";
For the hat trick, Dart now also has adjacent String literals:
var reallyLongLine = 'Sometimes you just need to work with really long lines '
'and a triple quotes multi-line string will not work. Luckily '
'Dart will automatically concatenate adjacent string literals '
'just like thing!';
'and a triple quotes multi-line string will not work. Luckily '
'Dart will automatically concatenate adjacent string literals '
'just like thing!';
Both the Dart VM and the Dart to JavaScript compiler already support adjacent string literals, so we encourage you to remove all uses of + for string concatenation, as + on String will be removed soon.
Summary
There are other changes to the Dart language spec with version 0.08, so I encourage you to browse the change log in the spec itself.In this post, I covered lazy initialization for statics, new equality semantics, cascaded method invocations, and removal of the + operator for string concatenation.
As always, the Dart team wants you to join the discussion. Please join the mailing list or enter feature requests and bug reports to dartbug.com. A good way to get early notification of some language changes is to follow the Dart News and Updates feed.