Maintainable Web Programming – Reviewing Dart

When developing modern web applications which should run on any major web browser and without the client’s need to install extra software, there is no way around using this programming language we all love: JavaScript. I personally appreciate its low type safety, its difference between null and undefined, the lack of OOP concepts, the fact that one should avoid writing native code if you want to ensure cross-browser compatibility and many other little things that make developers happy. If you understand the irony, you will be interested in a new language called “Dart”, introduced by Google about one year ago. I came across this project when I did some research about how to make our JavaScript code base more maintainable. Read the following article to learn about the language’s basic concepts, what I find highly helpful and why I decided to not use it for my current projects.

The Facts

Dart is an open source project, introduced and driven by Google. It includes a class based programming language which allows proper structuring of your client-side code and should be easy to understand for many experienced software developers due to its familiar syntax. Dart code can be both executed in a virtual machine and in any modern browser since it can be compiled to native JavaScript. The idea is not new at all, there are many languages which compile to JavaScript. However, Google tries to get Dart becoming a new standard and even aims a native code support in all major browsers.

Though they introduced the first preview version about one year ago in October, it is important to understand, that there is still no stable release. The version I tested was a “Technical Preview” release 0.11 from June 2012 and, unfortunately, there is no timeline for further releases. A smart way of getting rid of deadline pressure. A bad thing for users who like to plan things.

Object Oriented Programming (OOP)

Let me show what I love about this language. C# and Java developers should already feel very familiar with following snippet:

#library("mylib");
#import("dart:html");

class MyWidget implements MyInterface {
  static final int MYCONST = 41;
  Element _element;
  
  MyWidget(String elementId) {
    _element = query("#$elementId");
  }
  
  String getCurrentColor() {
    return _element.style.color;
  }
}

void main() {
  var widget = new MyWidget("container");
  query("#mytext").text = widget.getCurrentColor();
}

Dart supports interfaces, inheritance, exceptions, scopes and generics. Not sure if it is a bad or good thing, but Dart also offers other ways of declaring variables and methods. I recommend to have a look at the Dart Language Tour to see more about the syntax and basic features.

I love it because it allows a minimum effort to let application developers understand and enhance client-side code. It lowers the risks and costs of a strict separation between UI and backend developers.

Libraries

Eventually a proper way to structure your code base is the “library” concept. It is similar to “packages” in Java. You can group your code and control its visibility. If you want to use a class from a different library, you need to import it first (see code snippet in previous paragraph). This enables better dependency management and reusability of code through multiple projects. You cannot just call a function any more of that you do not know where it is from.
So far, libraries also control the visibility of class members. Class members starting with an underscore (“_”) are private to its library only. Dart’s “private” is so to say what the default access modifier in Java means.
Though the exact syntax is already announced to be changing in the next releases, the library concept is certainly Dart’s big plus.

Official Tools

When developing Dart applications, you will need at least the Dart Software Development Kid (SDK). It consists of the Dart-to-JavaScript compiler (dart2js), a Virtual Machine (VM) and core libraries.
Apart from the SDK, the Dart guys also developed the Dart editor. It is an Eclipse based IDE for writing Dart code. I could not figure out why they created an own IDE, rather than providing it as an Eclipse plugin. Anyway, the good thing is that both the SDK and Dart editor are free and can be downloaded at the official website.

The Editor

As already mentioned, the official editor is a basic distribution of Eclipse. It offers Dart specific wizards and very helpful syntax highlighting.

Dart Editor Screenshot

Pros:

  • If you are Eclipse-experienced, you do not have to learn new shortcuts or get used to a new look and feel.
  • Better syntax highlighting of methods and variables than I am used to Eclipse plugins I know.
  • Debugger with break points.
  • Code Cleanup feature, which is not fully implemented yet, but would migrate code to libraries, shorten exception catch blocks and generate getters.

Cons:

  • Does not fully support Javadoc commentaries. You need to close comments by yourself and the autocomplete result list does not display comments. Btw, “@param” or other tags are not supported in Dart.
  • No plugin for unit tests! Though Dart provides a unit test library (I come to that later), the editor does not provide a separate executor or graphical reports of test code.
  • The autocomplete feature detects your own classes from different libraries, but the editor cannot add the appropriate import statement automatically. You need to maintain the import statements by yourself.
  • Not the editor’s fault: Some of the dart libraries (e.g. “dart:html”) do not contain any useful commentaries. Either comments are missing or are useless (e.g., simply repeating the method name or commenting get/set methods only with “get the value / set the value”). Though you have a specialized editor, you will still need your web browser open to search the internet for the (possible) correct usage of methods like AudioBuffer.getChannelData(int).
  • Having a separate IDE only for client-side code disturbs me. It probably makes sense only if you implement static UI components without server communication. I feel that a proper integration into the major IDEs would have been the better solution, in particular if you want to run Dart code directly in your application. At least there is such a plugin for IntelliJ IDEA. And good news is that there are efforts to have the editor as an Eclipse plugin as well.

Accessing and Manipulating DOM

One of the language’s real strengths is its HTML library which allows querying and manipulating DOM elements in a very easy way. In my opinion even better than the jQuery API, because the developer has to decide whether he expects a collection or a single node when he queries the DOM tree and he is also forced to use separate functions when adding event listeners. Dart uses also CSS selectors, so the following snippet should be self-explanatory to web developers:

#import('dart:html');

void main() {
  // decorate single element
  query("#mytext").on.click.add(hideElement);
  
  // coloring all paragraphs
  queryAll(".contentArea p").forEach(colorElement);
}

void hideElement(Event event) {
  event.srcElement.dynamic.hidden = true;
}
void colorElement(Element element) {
  element.style.color = "red";
}

Another nice thing is that collections are not arrays or any library specific objects which can be anything, like the jQuery object, but they are actual collection instances. Hence, you always can use convenient methods like .isEmpty(), .contains('foo') or .add(anotherObject).

Unit Testing

Dart does not know test classes with annotation driven test methods, as we know it, for example, from Java/JUnit. Instead, Dart provides the “unittest” library which basically comes along with the two methods:

  • test(String testName, functionToTest);
  • expect(actualValue, expectedValueMatcher);

and a set of “matchers”, e.g. isNotNull(..), equals(..) or greaterThan(..). So the concept is pretty similar to QUnit, but with the “expect” function in between and with much more matcher/assertion functions.

Your test code would be embedded in a test HTML page and look like the following, at least theoretically:

#import('package:/unittest/unittest.dart');
#import('../mylib/mywidget.dart');

var widget;

void testGetCurrentColor() {
  test('currentColor', () =>
      expect(widget.getCurrentColor(),
          equals("#CCCCCC"))
  );
}

void main() {
  widget = new MyWidget('testelement');  
  testGetCurrentColor();
}

Only theoretically, because I could not even get the code running due to a Windows path issue in the package resolver (version 0.11).

There is nothing like a test suite. So you need to execute every test page separately and check the console output or write some scripts which do that for you. Getting unit tests for the presentation layer running on a continuous integration (CI) server will be still a nightmare.

The unit testing library looks at least better than what I know from existing JavaScript solutions due to a larger set of available matchers and the ability to even create custom matchers. But the lack of editor support and the somewhat complex syntax will certainly not increase the motivation and joy of doing test driven development (TDD).

Integration of external JavaScript libraries

This is my biggest concern. So far, it looks like external JavaScript cannot be embedded in Dart program code and hence it is not possible to integrate UI widgets from JavaScript libraries such as jQuery, YUI, Prototype, etc. The only little hope here is that the Dart guys at least are planning to implement a solution which would consist of autogenerated RPC “stub code”, but one can doubt that this would enable a reliable integration. We have to hope that Dart either puts some more effort on this or some smart guys start developing Dart based libraries which are as rich and helpful as existing ones in the JavaScript world.

Do not use it, yet

Keep in mind that Dart is a very young language with many future API changes. Just have a look at the Milestone 1 Language Changes log: Hopefully you have not started to staple strings with the “+” operator, as you know it from Java(Script) and as it has been supported before in Dart.
As of now (September 2012), even the official website states: “If your web app is something that needs to be reliable, we really recommend waiting until Dart is more mature.”

I like to see that there are efforts to get rid of JavaScript code from our projects and to not let unexperienced web developers stumble across the ECMAScript’s traps any more. Google as a strong development lead, OOP, Java-like syntax and the library concept look promising. However, the language is far away from being mature enough to consider it for real world applications. We will also see if Dart can compete with the number of widgets and plugins of the already established JavaScript libraries out there.

Advertisements

Tags: , ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: