Skip navigation
Help

Dart

warning: Creating default object from empty value in /var/www/vhosts/sayforward.com/subdomains/recorder/httpdocs/modules/taxonomy/taxonomy.pages.inc on line 33.

Google has released an experimental version of the Chromium web browser with support for the company’s new Dart programming language. Dart, which is Google’s attempt to improve on JavaScript, has thus far not enjoyed much support outside of Google, but the company continues to push forward with its own efforts.

The new development preview version of the Chromium browser, the open source version of Google’s Chrome browser, contains the Dart Virtual Machine. This release, which Google is calling “Dartium,” can be downloaded from the Dart language website. At the moment it’s available only for Mac OS X and Linux. Google says a Windows version is “coming soon.” Keep in mind that this is a preview release and intended for developer testing, not everyday use.

Google originally created Dart to address the shortcomings of JavaScript and ostensibly speed up the development of complex, large-scale web applications.

While there is much programmers might like about Dart, it is, like Microsoft’s VBScript before it, a nonstandard language from a single vendor created without any regard for the existing web standards process. The new Dartium release is the first browser to include a Dart Virtual Machine and, based on the response from other browser makers to the initial release of Dart, likely the only browser that will ever ship with a Dart VM. For its part Google says it plans to incorporate the experimental Dart VM into Chrome proper in the future.

The company also has a plan for all those browsers that aren’t jumping on the Dart bandwagon — a compiler that translates Dart to good old JavaScript. In this scenario Dart ends up somewhat like CoffeeScript, a JavaScript abstraction that makes more sense to some programmers.

For more details on the new Dartium browser and the latest improvements to the Dart VM, be sure to check out the Google Code Blog announcement.

0
Your rating: None

In this post I want to give you a short introduction to Google’s new language called Dart.

Personally I am quite disappointed that Dart looks a lot like Java 8 with some tweaks here and there. Although the language is in its early stages I wonder why pattern matching was not a top-priority to the language team since Dart relies heavily on message passing. More on that in a second.

Since Dart should scale from small scripts to full applications it is nice to see support for generics from the start, optional typing and functions as first-class citizens.
However that makes Dart look more like a better Java than JavaScript.

What makes Dart more of a web language is how you perform concurrent computations. This is done by shared-nothing message passing. The same way you do it with workers in JavaScript, actors in Erlang or Scala and hopefully quite soon in the Flash Player. We should not forget Go in this equation since it was also an effort to try out concurrency via channels that can send and receive messages. If we look a little bit more into Dart we can see some of the same ideas.

A worker in Dart are called Isolate [1]. This makes sense since it runs completely isolate from the rest of your program. What is nice about the Dart approach is that you do not have to deal with files anymore when using an Isolate. JavaScript requires you to perform the task of having some special file lying around somewhere that adheres to the Worker protocol. When I write my application, I do not want to think about files that have some special top-level logic in them. Especially, I do not want to write a custom file at runtime using a blob-builder.

Dart embeds this from the start just like Go does. You will have a lot of Isolate objects communicating via a SendPort [2] and a ReceivePort [3]. The Promise<T> [4] is just like Java’s Future<T> a holder for a value that can be computed later. I just wonder why they did not implement a read-only and write-only view on them. It would be nice if Promise<T> would be extended with methods like map, flatMap etc. because your code would be less spaghetti.

With no further ado I would like to explain some code now that you know how Dart works. Basically we calculate the n-th Fibonacci number with a very expensive approach. You would never do this in reality. Let us define fib(x) = fib(x - 1) + fib(x - 2) with fib(1) = 1 and fib(2) = 1. So fib(3) is fib(2) + fib(1) which is 1 + 1. Sorry for to bore you to death.

If we implement this in pseudo-code we get something like this:

int fib(int x) {
  return x < 3 ? 1 : fib(x - 1) + fib(x - 2);
}

If you would like to make this multi-threaded with Scala you could wrap the calls to fib into a Future[Int] like this:

def fib(x: Int) =
  x match {
    case 1 | 2 => 1
    case _ =>
      val n1 = future { fib(x - 1) }
      val n2 = future { fib(x - 2) }
      n1() + n2()
  }

We want to do the same with Dart. Since it is a language targeted for the web we get no access to blocking calls. The Scala code blocks when n1() or n2() is called. In layman's terms: we wait until the value has been computed.

Since there is no support for continuation passing style like C#'s async we have to write a lot of callbacks now.

This is the entry-point for the Dart version of this:

main() {
  int n = 7;

  print("Computing fib($n) ... ");

  new FibIsolate().spawn().then(
    (port) =>
      port.call(n).receive(
        (value, port) => print("fib($n) = $value")
      )
  );
}

First of all we see string-interpolation which is nice. Then we create a FibIsolate which I will show you in a second. When you create an Isolate it does not do anything so we have to call spawn() to perform the actual computation. However spawn returns us only a Promise<SendPort> which we can only use when available. This is done with the then method. then takes a function as an argument.
There are multiple ways we could do this. then((x) => ...) is the same as then((x) { ... }). You are only allowed to use the first form for a single expression but you do not need to write all that boilerplate. In fact you are even allowed to omit a semicolon. Hell Yeah!

So when we get a SendPort which happens to be the case when our function is called we can send some value via the call method. Why use call and not send? call returns a ReceivePort which allows us to wait for the result. We do this by calling receive on the ReceivePort with a closure to print the value we get back.

Now let's have a look at the implementation of FibIsolate.

class FibIsolate extends Isolate {
  main() {
    port.receive((n, replyTo) {
      switch(n) {
        case 0:
          replyTo.send(0); break;

        case 1:
        case 2:
          replyTo.send(1); break;

        default:
          Promise<int> n1 = new Promise<int>();
          Promise<int> n2 = new Promise<int>();

          new FibIsolate().spawn().then(
            (port) =>
              port.call(n - 1).receive(
                (n, port) => n1.complete(n)
              )
          );

          new FibIsolate().spawn().then(
            (port) =>
              port.call(n - 2).receive(
                (n, port) => n2.complete(n)
              )
          );

          n1.then(
            (x) => n2.then(
              (y) => x + y
            )
          ).flatten().then(
            (x) => replyTo.send(x)
          );
      }
    });
  }
}

First of all we have to extend from Isolate. The main() function of an Isolate is its entry-point. Now something that really bugs me is the amount of indentation. Nearly every second Isolate which you are going to write has this form. Your actual logic starts at the fifth indentation level.

In the main method we immediately start listening for messages via the Isolate's ReceivePort. Then we need to react on the message via a switch case. Now although it might look simple in this case it is very sad that Dart does not come with proper pattern matching since you will need to write a lot of switch-case in Dart code. If you have ever seen pattern matching in action using Scala you never want to go back to a dumb switch statement.

In the default case it gets a little bit more interesting. We need to spawn two new instances of FibIsolate since we want to do this recursive. We need to receive their result and when we have both results we want to perform the addition and send our value back to the caller.

Since there are no blocking calls we create a Promise<int> for each FibIsolate. When can complete the Promise<int> once we receive a value from an isolate. This allows us to combine both Promise<int> objects and wait on their results. Why do we not nest the FibIsolate you might ask. Because we want to spawn both at the same time so the computation can happen in parallel.

The actual nesting happens in the n1.then((x) => n2.then((y) => x + y)) construct. However the return type of n1.then((x) => n2.then((y) => ...) is no longer Promise<int> but Promise<Promise<int>>. Fortunately someone thought about this case and there is a flatten() method which turns the Promise<Promise<int>> into a Promise<int> we just have to await and the finally reply with the computed value.

However remember the definition of fib(x)? The case for 1, 2 and 0 is quite simple because we can reply with the value immediately. And we do this by calling send on the SendPort which I named replyTo.

You can take a look at the full example running in the browser here.

What I like about Dart is that someone thought about workers and made them first-class citizens. Pattern-matching is on the road map and they will hopefully copy Scala. There are however a lot of things that I dislike.

  1. Semicolons are required but optional for shorthand (x) => x
  2. The return keyword is required but optional when used with (x) => x
  3. No control about concurrency. Are my isolates CPU or I/O bound?!
  4. No syntactic sugar for writing an Isolate
  5. Not DSL friendly like Scala or maybe even Kotlin
  6. int disguises itself as a primitive but is an object instead
  7. Missed the opportunity to embed continuation passing style into the language from the start
  8. Function is the only function-type

The type-system can be argued as well. I did not find anything about type erasure yet. Personally Dart feels much more like Java and Go than JavaScript. But in the end I would be quite happy if Dart could replace JavaScript since it is a step in the right direction from my personal point of view.

[1] http://www.dartlang.org/docs/api/Isolate.html#Isolate::Isolate
[2] http://www.dartlang.org/docs/api/SendPort.html#SendPort::SendPort
[3] http://www.dartlang.org/docs/api/ReceivePort.html#ReceivePort::ReceivePort
[4] http://www.dartlang.org/docs/api/Promise.html#Promise::Promise

flattr this!

0
Your rating: None

It’s not everyday that someone tries to add a new programming language to the web. There’s a good reason for that. The great trinity of web development — HTML, CSS and JavaScript — while not perfect has proved itself highly flexible and capable of adapting as it evolves, which, in the end, might be more important than perfection.

But, regardless of how well those three have served the web thus far, they are not enough for Google, which is hoping the web will now embrace Dart, Google’s brand new programming language for “structured web programming.”

The first hint of Dart surfaced about a month ago when an internal Google memo was leaked onto the web (the memo itself dates from 2010). In it Google claims that “JavaScript has fundamental flaws that cannot be fixed merely by evolving the language.” The answer, for Google, was to go off and create its own homebrewed solution.

That solution is Dart, a “class-based optionally typed programming language for building web applications.”

Lars Bak, a software engineer working on Dart, says the language is designed to work with every thing from “a one-person project without much structure to a large-scale project needing formal types in the code to state programmer intent.”

In other words, Dart is aiming to be a one-size-fits-all solution for writing apps on the web. Dart has been built from the ground up with this goal in mind. Indeed Dart offers some interesting tools, including optional types and the ability to declare private methods via an underscore. Unfortunately for Dart, a couple of novelties don’t seem to be winning over programmers. The Hacker News discussion thread on Dart is full of rather barbed critiques with hardly a supportive voice to be heard.

Dart on the web

Appealing to programmers is only half of what Dart needs to succeed, it also has to work well on the open web. For that Google has two solutions.

The first and ideal solution will be to execute Dart code in a browser-native virtual machine (very similar to how JavaScript is handled today). Of course that means the rest of the browser makers need to join Google in supporting Dart. Because that isn’t likely to happen any time soon, nor will it ever happen for legacy web browsers, Google has a fallback plan — a compiler that translates Dart code to JavaScript.

While the JavaScript compiler solution will mean slower web apps, it also means that Dart apps would always be able to run, regardless of the browser in question. That’s good for older browsers, but it also raises some questions about where Google plans to go with Dart.

Essentially Google has set up a two-tier system for running Dart in the browser, and that is where Dart might run afoul of the open web.

Prior Dart Art

The leaked Google memo that appeared on the web last month created a tempest in the web standards community teacup. The idea that Google had a secret project designed “to replace JavaScript as the lingua franca of web development” did not sit well with those who support open web standards.

The company appears to have backed off that stance somewhat for the official release. In fact Google hardly mentions JavaScript in its Dart announcement and Lars Bak tells CNet that Dart is “not going to replace JavaScript… JavaScript is a cornerstone of the Web today, and it will continue to be for a long, long time.”

That message may be too little, too late. Publicly Google may now be pushing the message that Dart is complimentary to JavaScript, but the blunter language and goals outlined in the leaked memo are already out there, fresh in developers’ minds. That, combined with Google’s less than stellar track record with its “open” projects may make it difficult for Dart to find supporters.

While Dart is open source and available for anyone to use, Google does not have a strong record of fostering open projects, that is, projects where the community can not just download and compile code (Andy Rubin’s “definition of open“) but can actually have a hand in creating features and guiding the direction of the project.

Until the latter component is well established don’t expect other browser makers to adopt Dart. So long as Google controls the strings it’s unlikely its arch rivals like Microsoft and Apple will support Dart.

Without that support Dart won’t be running in a virtual machine; instead it will fall back to running as JavaScript. That effectively means that, while Dart will run in any browser, it will likely have subpar performance in any browser lacking the virtual machine.

What standards proponents fear is a web where only Google’s Chrome browser ever fully supports Dart. That would mean that, while Dart apps would work everywhere, they’d be significantly faster in Chrome. That would send the web back to the bad old days of “works best in Internet Explorer” websites, only this time around it would be “works best in Google Chrome.”

Future Dart

It’s possible that Google will use Dart to finally create a true community-driven project. The company has already said it plans to eventually submit Dart for standardization, which would certainly help.

It’s too early to write off Dart, but it’s also too early to say it will be anything more than a novelty Google uses in its own apps (like WebP or even SPDY). Even if Dart can convince both developers and browser makers to jump on board, don’t look for Dart to become the “lingua franca of web development” any time soon.

See Also:

0
Your rating: None