Game of Darts

JavaScript is great but...

  • don't forget your vars, or
  • semicolons, or
  • this, or
  • ===
  • no prototypical privacy
  • no lexical closures,
  • no namespaces,
  • no package sharing,
  • no dependency management

No stdlibs

* There's a reason 65% of webpages include jQuery

@MarkBennett

So how does Dart fit in?

Familiar

Productive

Ubiquitous

Familiar


import 'dart:html';

main() {
  var msg = querySelector('#msg');
  var btn = new ButtonElement();
  btn.text = 'Click me!';
  btn.onClick.listen((e) => msg.text = 'Dart!');
  document.body.children.add(btn);
}
            

Insprired by

  • JavaScript
  • CoffeeScript
  • Ruby
  • Java
  • C#

Short function definitions


// Who needs a function keyword?
awesome(int num) {
  return "$num MILLION DOLLARS!!!";
};

// One liner callbacks are easy
// Notice, the return is implied
var some = (num) => "$num MILLION DOLLARS!!!";

print(awesome(5));  // 5 MILLION DOLLARS!!!
print(some(5));     // 5 MILLION DOLLARS!!!
            

Lexical Closures


awesome() {
  var a = "outside";
  print a;              // outside

  if (true) {
    var a = "inside";

    print a;            // inside
  }
  print a;              // outside
}
            

Classes


class Sauce {
  applyTo(meal) {
    print("$meal, with sauce.");
  }
}

class HotSauce {
  applyTo(meal) {
    print("$meal, with hot sauce. SPICY!");
  }
}

new Sauce().applyTo("Burger");      // Burger, with sauce.
new HotSauce().applyTo("Chips");    // Chips, with hot sauce. SPICY!
            

Mixins


abstract class Sauce {
  applyTo(meal) => throw "implement this";
}

abstract class Spicy {
  warn() => print("Don't drink me!");
}

class HotSauce extends Sauce with Spicy {
  applyTo(meal) => print("$meal, with hot sauce. SPICY!");
}

new HotSauce()
  ..applyTo("Chips")    // Chips, with hot sauce. SPICY!
  ..warn();             // Don't drink me!
            

main() function


void main() {
  print("It's like writing C again!");
  print("No guessing which <script> tags are running code."); 
}
            

Private methods


class SuperHero {
  _real_identity;

  SuperHero(real_identity) => _real_identity = real_identity;
}

// In another library
var super_man = new SuperHero("Clark Kent");
super_man._real_identity;                     // Private to library
            

Optional, named and default params


setFlags({bool verbose: false, bool dry_run: false}) {
  // use verbose and dry_run here
}

log(message, [Logger logger]) {
  if (?logger) {
    logger.log(message);
  } else {
    print(message);
  }
}

void main() {
  setFlags(dry_run: true);
  log("Hello!");
}
            

Typedefs


typedef int Compare(int a, int b);

int sort(int a, int b) => a - b;

main() {
  assert(sort is Compare);  // True!
}
            

Metadata


import 'dart:mirrors';

class MyAnnotation {
  final String note;
  const MyAnnotation(this.note);
}

@MyAnnotation('Go! Go! Gadget!')
class Annotated {
}

main() {
  ClassMirror mirror = reflectClass(Annotated);
  String note = mirror.metadata.
      where((a) => a.type.reflectedType == MyAnnotation).
        first.reflectee.note;
}
            

Productive

No variable hoisting


my_func() {
  a = 0;      // Doesn't define window.a
              // It just doesn't compile
}
            

Functions without classes


i_have_no_class() {
  print("rolling without any hommies.");
}
            

Function closures include this


class MyHandler {
  on_event_callback(e) {
    // When this is called, this != window
  }
}

main() {
  handler = new MyHandler();
  btn.onClick.listen(handler.on_event_callback);
}
            

Method Cascades


class Person {
  String name;
  greet() => print("Hi, my name is $name!");
}

main() {
  Person bob = new Person()
    ..name = "Bob"
    ..greet();               // "Hi, my name is Bob!"
}
            

Constructor shortcuts


class Simple {
  _name;
  _description;

  Simple(this._name, this._description);
}

void main() {
  var simple = new Simple("Bob", "I'm awesome!");
}
            

Named contructors


class Simple {
  _name;
  _description;

  Simple(this._name, this._description);
  Simple.withDefaults() {
    _name = "Default";
    _description = "No magic here.";
  }
}

void main() {
  var simple = new Simple.withDefaults();
}
            

Factory methods


class Singleton {
  static Singleton _singleton;

  factory Singleton() {
    if (_singleton == null) {
      print("Creating singleton");      
      _singleton = new Singleton._internal();
    }
    return _singleton;
  }
  Singleton._internal() { }
}

void main() {
  var a = new Singleton(),    // Creating singleton
      b = new Singleton();    // Same as the first!
}
            

Robust Standard Library

Futures


future_worker() {
  Completer completer = new Completer();
  new Timer(const Duration(seconds: 1), () {
    completer.complete("done!");
  });

  return completer.future;
}

main() {
  future_worker().then((data) => print("In the future!"));
}
            

Streams


my_file.openRead().transform(new Latin1Decoder()).
  listen((line) => print(line));

btn.onClick.listen((evt) => print("Button Click!"));
            

Isolates and Ports


import 'dart:isolate';

runningInAnIsolate(SendPort replyTo) {
  replyTo.send("Hello from the isolate!");
}

main() {
  ReceivePort port = new ReceivePort();
  Isolate.spawn(runningInAnIsolate, port.sendPort);

  port.listen((msg) => print(msg),
              onDone: () => port.close());
}
            

Libraries & Parts


// In ballgame.dart
library ballgame;   // Declare that this is a library named ballgame.

import 'dart:html'; // This app uses the HTML library.

// Include other files in the library
part 'ball.dart';
part 'util.dart';

// In ball.dart
part of ballgame;

// In your code
import "package:ballgame";
            

Go to the Pub

Standard package creation and sharing

~720 packages

Dart Editor

Optional Types

Tree Shaking

VM Snapshots

Ubiquitous

Run the same code on:

  • Server
  • Browser

Compile to JavaScript

Interop with JavaScript


import 'dart:js' as js;

main() {
  // Bind a Dart function to a JavaScript name
  js.context["greeter"] = (name) => "Hello, from $name!";

  // Call the JavaScript function we just bound
  var greeting = js.context.callMethod("greeter", ["Dart"]);
  print(greeting);

  // Call the same Dart function we bound, in JavaScript
  // console.log(greeter("JavaScript"));
}
            

The Big Picture

Dart is open-source, built by solid people who build V8, JVM, and Smalltalk VMs

Dart succeeds if the web moves forward

Learn More

Questions?