第 1 張,共 55 張

Kasper Lund

Seth Ladd

Chrome Dev Summit 2013

#dartlang

第 2 張,共 55 張

  • Language and libraries
  • Tools
  • VM
  • Compiler to JavaScript

#dartlang

第 3 張,共 55 張

1.0

Stability you can count on.

#dartlang

第 4 張,共 55 張

Lightning Tour

  • Syntax
  • Semantics
  • Structure

#dartlang

第 5 張,共 55 張

class Hug {

Simple syntax, ceremony free

Familiar

#dartlang

第 6 張,共 55 張

class Hug {

num strength;

Hug(this.strength);

Simple syntax, ceremony free

Terse

#dartlang

第 7 張,共 55 張

class Hug {

num strength;

Hug(this.strength);

Hug operator +(Hug other) {

return new Hug(strength + other.strength);

}

Simple syntax, ceremony free

Operator overriding

#dartlang

第 8 張,共 55 張

class Hug {

num strength;

Hug(this.strength);

Hug operator +(Hug other) {

return new Hug(strength + other.strength);

}

void patBack({int hands: 1}) {

// ...

}

Simple syntax, ceremony free

Named, optional params w/ default value

#dartlang

第 9 張,共 55 張

// ...

Hug operator +(Hug other) {

return new Hug(strength + other.strength);

}

void patBack({int hands: 1}) {

// ...

}

String toString() => "Embraceometer reads $strength";

}

Simple syntax, ceremony free

One-line function

#dartlang

第 10 張,共 55 張

// ...

Hug operator +(Hug other) {

return new Hug(strength + other.strength);

}

void patBack({int hands: 1}) {

// ...

}

String toString() => "Embraceometer reads $strength";

}

Simple syntax, ceremony free

String Interpolation

#dartlang

第 11 張,共 55 張

Clean semantics and behavior

#dartlang

第 12 張,共 55 張

Clean semantics and behavior

  • Only true is truthy
  • There is no undefined, only null
  • No type coercion with ==, +

Examples:

#dartlang

第 13 張,共 55 張

"hello".missing // ??

Missing getter?

Class 'String' has no instance getter 'missing'.

NoSuchMethodError : method not found: 'missing'

Receiver: "hello"

Arguments: []

Logical

#dartlang

第 14 張,共 55 張

'hello' > 1 // ??

String compared to number?

Class 'String' has no instance method '>'.

Logical

#dartlang

第 15 張,共 55 張

var foo = 'top-level';

main() {

if (true) { var foo = 'inside'; }

print(foo); // ?? What will this print?

}

Variable scope?

top-level

Logical

No hoisting

#dartlang

第 16 張,共 55 張

class AwesomeButton {

AwesomeButton(button) {

button.onClick.listen((Event e) => this.atomicDinosaurRock());

}

atomicDinosaurRock() {

/* ... */

}

}

Scope of this?

Lexical this

#dartlang

第 17 張,共 55 張

library games;

import 'dart:math';

import 'players.dart';

class Darts {

// ...

}

class Bowling {

// ...

}

Player findOpponent(int skillLevel) {

// ...

}

Scalable structure

Functions

Classes

Libraries

Packages

Mixins

Interfaces

#dartlang

第 18 張,共 55 張

Compiling to JavaScript

#dartlang

第 19 張,共 55 張

Our goals

  • Small code
  • Fast code
  • Retain Dart semantics

#dartlang

第 20 張,共 55 張

We need an optimizing compiler

function inlining

loop-invariant code motion

type propagation

global value numbering

redundant load elimination

dead code elimination

… and much, much more!

#dartlang

第 21 張,共 55 張

Simple Dart method

main() {

var p = new Point(2, 3);

var q = new Point(3, 4);

var distance = p.distanceTo(q);

...

}

#dartlang

第 22 張,共 55 張

… compiles to simple JavaScript

main: function() {

var p, q, distance;� p = new Point(2, 3);� q = new Point(3, 4);� distance = p.distanceTo$1(q);

...�}

#dartlang

第 23 張,共 55 張

… compiles to simple JavaScript

main: function() {

var p, q, distance;� p = new Point(2, 3);� q = new Point(3, 4);� distance = p.distanceTo$1(q);

...�}

arity is encoded in method name

#dartlang

第 24 張,共 55 張

Tree shaking

main

Library

baz

foo

bar

boo

imports

calls

baz

main

foo

bar

dart2js

#dartlang

第 25 張,共 55 張

Two-level tree shaking

Resolver queue

Parser

Resolver

Compilation queue

Builder

Code generator

Emitter

File reader

Diet parser

#dartlang

第 26 張,共 55 張

DeltaBlue

Constraint solving algorithm

#dartlang

第 27 張,共 55 張

DeltaBlue: Constraint solver

#dartlang

第 28 張,共 55 張

DeltaBlue: Working with constraints

void addConstraintsConsumingTo(Variable v, List<Constraint> coll) {

Constraint determining = v.determinedBy;

for (int i = 0; i < v.constraints.length; i++) {

Constraint c = v.constraints[i];

if (c != determining && c.isSatisfied()) {

coll.add(c);

}

}

}

#dartlang

第 29 張,共 55 張

Same semantics without types

addConstraintsConsumingTo(v, coll) {

var determining = v.determinedBy;

for (var i = 0; i < v.constraints.length; i++) {

var c = v.constraints[i];

if (c != determining && c.isSatisfied()) {

coll.add(c);

}

}

}

#dartlang

第 30 張,共 55 張

DeltaBlue: Unoptimized

addConstraintsConsumingTo$2: function(v, coll) {

var determining, t1, t2, t3, i, t4, c;

determining = v.get$determinedBy();

t1 = v.constraints;

t2 = getInterceptor$as(t1);

t3 = getInterceptor$a(coll);

i = 0;

while (true) {

t4 = t2.get$length(t1);

if (typeof t4 !== "number") throw new IllegalArgumentError(t4);

if (!(i < t4)) break;

c = t2.$index(t1, i);

if ((c == null ? determining != null : c !== determining) && c.isSatisfied$0() === true) {

t3.add$1(coll, c);

}

++i;

}

}

Simply not good enough!

#dartlang

第 31 張,共 55 張

DeltaBlue: Number checks

addConstraintsConsumingTo$2: function(v, coll) {

...

while (true) {

t4 = t2.get$length(t1);

if (typeof t4 !== "number") throw new IllegalArgumentError(t4);

if (!(i < t4)) break;

...

but we want to compare it against one

we don’t know length is a number

so we have to explicitly check

#dartlang

第 32 張,共 55 張

Our challenge ...

clean semantics and unsurprising behavior

without

extra checks when compiled to JavaScript

#dartlang

第 33 張,共 55 張

Global optimizations

#dartlang

第 34 張,共 55 張

Global optimizations

  • Dart is structured and allows whole program analysis

  • Understanding your program’s structure enables:
    • Code navigation and great refactoring tools
    • Global compile-time optimizations

#dartlang

第 35 張,共 55 張

Inferring types iteratively

main() {

foo(42);

}

foo(x) {

bar(x);

}

bar(y) {

if (y is String) print(y);

else foo(“$y”);

}

bar is called with a string

foo is called with an int

bar is called with an int

foo is called with a string

print is called with a string

#dartlang

第 36 張,共 55 張

Inferring types iteratively

main() {

foo(42);

}

foo(x) {

bar(x);

}

bar(y) {

if (y is String) print(y);

else foo(“$y”);

}

x :: int | String

y :: int | String

#dartlang

第 37 張,共 55 張

DeltaBlue

addConstraintsConsumingTo(v, coll) {

var determining = v.determinedBy;

for (var i = 0; i < v.constraints.length; i++) {

var c = v.constraints[i];

if (c != determining && c.isSatisfied()) {

coll.add(c);

}

}

}

#dartlang

第 38 張,共 55 張

Global type inference in action

addConstraintsConsumingTo(v, coll) {

var determining = v.determinedBy;

for (var i = 0; i < v.constraints.length; i++) {

var c = v.constraints[i];

if (c != determining && c.isSatisfied()) {

coll.add(c);

}

}

}

Array<subclass=Constraint>

null | exact=Variable

#dartlang

第 39 張,共 55 張

Global type inference in action

addConstraintsConsumingTo(v, coll) {

var determining = v.determinedBy;

for (var i = 0; i < v.constraints.length; i++) {

var c = v.constraints[i];

if (c != determining && c.isSatisfied()) {

coll.add(c);

}

}

}

v :: null | exact=Variable

coll :: Array<subclass=Constraint>

v.determinedBy :: null | subclass=Constraint

v.constraints :: Array<subclass=Constraint>

v.constraints.length :: int

v.constraints[i] aka c :: subclass=Constraint

c.isSatisfied() :: bool

#dartlang

第 40 張,共 55 張

Output without type inference

addConstraintsConsumingTo$2: function(v, coll) {

var determining, t1, t2, t3, i, t4, c;

determining = v.get$determinedBy();

t1 = v.constraints;

t2 = getInterceptor$as(t1);

t3 = getInterceptor$a(coll);

i = 0;

while (true) {

t4 = t2.get$length(t1);

if (typeof t4 !== "number") throw new IllegalArgumentError(t4);

if (!(i < t4)) break;

c = t2.$index(t1, i);

if ((c == null ? determining != null : c !== determining) && c.isSatisfied$0() === true) {

t3.add$1(coll, c);

}

++i;

}

}

526 characters

v :: null | exact=Variable

#dartlang

第 41 張,共 55 張

With type inference (1)

addConstraintsConsumingTo$2: function(v, coll) {

var determining, t1, t2, t3, i, t4, c;

determining = v.determinedBy;

t1 = v.constraints;

t2 = getInterceptor$as(t1);

t3 = getInterceptor$a(coll);

i = 0;

while (true) {

t4 = t2.get$length(t1);

if (typeof t4 !== "number") throw new IllegalArgumentError(t4);

if (!(i < t4)) break;

c = t2.$index(t1, i);

if ((c == null ? determining != null : c !== determining) && c.isSatisfied$0() === true) {

t3.add$1(coll, c);

}

++i;

}

}

v.constraints :: Array<subclass=Constraint>

#dartlang

第 42 張,共 55 張

With type inference (2)

addConstraintsConsumingTo$2: function(v, coll) {

var determining, t1, t2, t3, i, t4, c;

determining = v.determinedBy;

t1 = v.constraints;

t2 = getInterceptor$as(t1);

t3 = getInterceptor$a(coll);

i = 0;

while (true) {

t4 = t1.length;

if (typeof t4 !== "number") throw new IllegalArgumentError(t4);

if (!(i < t4)) break;

c = t1[i];

if ((c == null ? determining != null : c !== determining) && c.isSatisfied$0() === true) {

t3.add$1(coll, c);

}

++i;

}

}

v.constraints.length :: int

#dartlang

第 43 張,共 55 張

With type inference (3)

addConstraintsConsumingTo$2: function(v, coll) {

var determining, t1, , t3, i, , c;

determining = v.determinedBy;

t1 = v.constraints;

t3 = getInterceptor$a(coll);

i = 0;

while (true) {

if (!(i < t1.length)) break;

c = t1[i];

if ((c == null ? determining != null : c !== determining) && c.isSatisfied$0() === true) {

t3.add$1(coll, c);

}

++i;

}

}

condition is now simple enough to be an expression so we turn this into a for-loop

#dartlang

第 44 張,共 55 張

With type inference (4)

addConstraintsConsumingTo$2: function(v, coll) {

var determining, t1, t3, i, c;

determining = v.determinedBy;

t1 = v.constraints;

t3 = getInterceptor$a(coll);

for (i = 0; i < t1.length; ++i) {

c = t1[i];

if ((c == null ? determining != null : c !== determining) && c.isSatisfied$0() === true) {

t3.add$1(coll, c);

}

}

}

33% smaller than original JS output

coll :: Array<subclass=Constraint>

#dartlang

第 45 張,共 55 張

With type inference (5)

addConstraintsConsumingTo$2: function(v, coll) {

var determining, t1, , i, c;

determining = v.determinedBy;

t1 = v.constraints;

for (i = 0; i < t1.length; ++i) {

c = t1[i];

if ((c == null ? determining != null : c !== determining) && c.isSatisfied$0() === true) {

coll.push(c);

}

}

}

t1 can be initialized in for-loop

#dartlang

第 46 張,共 55 張

With type inference (6)

addConstraintsConsumingTo$2: function(v, coll) {

var determining, t1, i, c;

determining = v.determinedBy;

for (t1 = v.constraints, i = 0; i < t1.length; ++i) {

c = t1[i];

if ((c == null ? determining != null : c !== determining) && c.isSatisfied$0() === true) {

coll.push(c);

}

}

}

41% smaller than original JS output

c :: subclass=Constraint (not null)

#dartlang

第 47 張,共 55 張

With type inference (7)

addConstraintsConsumingTo$2: function(v, coll) {

var determining, t1, i, c;

determining = v.determinedBy;

for (t1 = v.constraints, i = 0; i < t1.length; ++i) {

c = t1[i];

if (c !== determining && c.isSatisfied$0() === true) {

coll.push(c);

}

}

}

48% smaller than original JS output

c.isSatisfied() :: bool

#dartlang

第 48 張,共 55 張

With type inference (8)

addConstraintsConsumingTo$2: function(v, coll) {

var determining, t1, i, c;

determining = v.determinedBy;

for (t1 = v.constraints, i = 0; i < t1.length; ++i) {

c = t1[i];

if (c !== determining && c.isSatisfied$0()) {

coll.push(c);

}

}

}

50% smaller than original JS output

#dartlang

第 49 張,共 55 張

DeltaBlue: Fully optimized

addConstraintsConsumingTo$2: function(v, coll) {

var determining, t1, i, c;

determining = v.determinedBy;

for (t1 = v.constraints, i = 0; i < t1.length; ++i) {

c = t1[i];

if (c !== determining && c.isSatisfied$0()) {

coll.push(c);

}

}

}

262 characters, same semantics

#dartlang

第 50 張,共 55 張

Performance

#dartlang

第 51 張,共 55 張

Workflow

#dartlang

第 52 張,共 55 張

Develop

w/ Dartium,

fast iterations.

The Cloud ™

upload build/ dir

Final testing

Testing on production browsers

dart2js

Tree shaking + minification

+ concatenation

JS

pub build

Smaller than some CSS frameworks

#dartlang

第 53 張,共 55 張

Ready to get started? Write a Dart app!

dartlang.org/codelabs/darrrt/

#dartlang

第 54 張,共 55 張

Dart 1.0 for the modern web

  • Platform you can use today
  • Easy to get started - dartlang.org
  • Compiles to JavaScript

#dartlang

第 55 張,共 55 張

WARNING:

Secret Google info beyond this point

#dartlang