Search This Blog

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.

Lazily Initialization for static variables

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."

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).

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 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!';

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.

Popular posts from this blog

Now, this has to have a built-in somewhere in Scala , because it just seems too common. So, how to convert an Array to a List in Scala? Why do I need this? I needed to drop to Java for some functionality, which in this case returns an Array. I wanted to get that Array into a List to practice my functional programming skillz. **Update**: I figured out how to convert Arrays to Lists the Scala way. Turns out it's a piece of cake. val myList = List.fromArray(Array("one", "two", "three")) or val myList = Array("one","two","three").elements.toList The call to elements returns an Iterator , and from there you can convert to a List via toList . Nice. Because my first version wasn't actually tail recursive, what follows is a true tail recursive solution, if I were to implement this by hand. The above, built in mechanism is much better, though. object ArrayUtil { def toList[a](array: Array[a]): List[a] = { d

In which I port a snazzy little JavaScript audio web app to Dart , discover a bug, and high-five type annotations. Here's what I learned. [As it says in the header of this blog, I'm a seasoned Dart developer. However, I certainly don't write Dart every day (I wish!). Don't interpret this post as "Hi, I'm new to Dart". Instead, interpret this post as "I'm applying what I've been documenting."] This post analyzes two versions of the same app, both the original (JavaScript) version and the Dart version. The original version is a proxy for any small JavaScript app, there's nothing particularly special about the original version, which is why it made for a good example. This post discusses the differences between the two implementations: file organization, dependencies and modules, shims, classes, type annotations, event handling, calling multiple methods, asynchronous programming, animation, and interop with JavaScript libraries. F

In which the virtues of automated mechanical arboreal pruning are extolled over quaint manual labor, as applied to web development build processes. The setup Ever notice how the primary bit of marketing for many traditional web programming libraries is their download size? Why is that? Check this out: Why does size matter so much for these libraries? Your first instinct is probably, "because the more bytes you shuttle across the wire, the slower the app starts up." Yes, this is true. I'd also say you're wrong. The primary reason that size matters for these libraries is because traditional web development has no intelligent or automated way to prune unused code so you can ship only the code that is used over the wire. The web is full of links, yet web dev has no linker The web development workflow is missing a linking step. A linker's job is to combine distinct project files into a single executable. A smart linker will only incl