Quantcast
Channel:
Viewing all articles
Browse latest Browse all 27

Thoughts on Dart

$
0
0

Lately I’ve started playing around with the Dart programming language by Google. The idea behind Dart, is that writing applications in javascript is really a painful act. Sure overtime many of us have gotten used to the various pain points, and there are conventional workarounds that have essentially become part of the ‘hidden standard’ of Javascript language. But why should we have to live with them? Just because it is, doesn’t mean we should be forced to deal with it!

Let me give you an example, in Javascript how would you go about creating a class (Note: Please don’t bother me with the semantics of class vs prototypical inheritance, just go with it for the sake of argument)? Well here’s one way:

Animal = function () {
    this.isAlive = true;
}
Animal.prototype = {
    eat: funciton(){},
    pray: function(){},
    love: function(){}
}

So far so good, no big deal here, now we can create many new Animal’s all we want. However what if we want to subclass Animal, to a more specific type of say Dog?

Well here’s where javascript’s faults come into play, there is no one way to do this so what you have is many people reinventing the wheel and confusion for new comers especially from other languages when they attempt to implement something as simple as creating a Dog that inherrits from Animal.

Here’s one way of doing it in Javascript:

Dog = function() {
    Animal.call( this ); // Call super's constructor
}
Dog.prototype = Object.create( Animal.prototype );

Here’s a different way of tackling the problem:

function extend( subclass, superclass ) {
 
    var originalSubclassPrototype = subclass.prototype;
 
    // Store the superclass prototype in a surrogate function
    var F = function(){};
    F.prototype = superclass.prototype;
 
    subclass.prototype = new F();
    subclass.superclass = superclass.prototype;
    subclass.prototype.constructor = superclass;
 
    for(var method in originalSubclassPrototype) {
        if( originalSubclassPrototype.hasOwnProperty(method) )
            subclass.prototype[method] = originalSubclassPrototype[method];
    }
 
}

Which is correct? Well the answer is both, there’s plenty of ways to skin a classy cat in Javascript, and these are just two of them, there’s plenty more out there as well. To me having too many ways to do something as simple as creating a subclass is a A Bad Thing.

In Dart there is only one way to create a Class, and only one way to create a subclass:

    class Vec2 {
        num x;
        num y;
        Vec2( this.x, this.y );
    }

That’s it, and in case you’re wondering about that sleek looking constructor, as you should be, well that is a special type of syntatic sugar shorthand in Dart that is the equivalent of:

    class Vec2 {
        num x;
        num y;
        Vec2( num pX, num pY ) {
            x = pX;
            y = pY;
        }
    }

How many times have you had to create a constructor where the first 10 lines were just simply setting the variables of the local instance? A lot i’m sure. Instead Dart allows you to simply state that the arguments passed in should be set to the respective local variables. Also notice that I did not type the word this. In Dart the scoping is already correct, so there is no need to explicitely type ‘this’ (although you can if you like).

Creating a subclass is equally as straight forward:

/// A circle is similar to a [Vec2] except it contains an area.
class Circle extends Vec2 {
  /// Radius of the [Circle]
  num radius;
 
  /// Creates a new [Circle] with [radius]
  Circle( num pX, num pY, this.radius) : super(pX, pY);
 
  /// Returns whether a point is contained within [this] [Circle]
  bool containsPoint( Vec2 p ) => ( distanceSquared(p) <= radius*radius );
}

That’s all there is to it, no confusion about which is the correct way, the “fastest” way, etc.

A couple of other things to notice here as well. Firstly are the comments. In Dart a comment that contains three slashes, ///, is considered a Documentation comment. It will be parsed by the built-in (!!) Dart-Doc generator. It even uses Markdown so you don’t have to write annoying HTML in your Documentation comments. Again notice the brackets around [Vec2], because Dart has full knowledge of your application, it knows to go and find the class Vec2 and link to it in the documentation.

So back to subclassing, notice our constructor:

Circle( num pX, num pY, this.radius) : super(pX, pY) {
    print("My radius is ${radius}");
}

Here we are using another two special constructs Dart provides for constructors. The first is the ‘initializer list’, which come from C++. They allow you to set properties separated by comma’s after the constructor, but outside of the function’s body. Notice the call to super, very straightforward.

Finally the last thing to notice is the string interpolation occuring in the ‘print’ function (essentially console.log). Here we have a single string, and inside we have a special syntax ‘${}’, where inside we can place an expression ( or value ), that dart will evaluate for us. No more having to concact strings with plus signs and making typos that are hard to spot.

Overall I’m very much liking the things that Dart is bringing to the table, best of all it compiles to Javascript so it will work on any modern browser. Currently Dart’s compiled javascript, runs at 80% speed of something written in vanilla javascript, and getting it’s not even at version 1.0 yet! Also worth mentioning that DartVM is already outperforming V8 in nearly all javascript benchmarks.

In the next post I’ll dissect a few more interesting things that I like about Dart, and a few who I dislike. In the meantime, don’t waste any time, go watch the screencast that sold me http://www.dartlang.org/docs/editor/


Viewing all articles
Browse latest Browse all 27

Trending Articles