My Dart Experience
Paul Brauner
|
About Me
• PhD in Logic / Types
• Postdoc in Languages
• Now at Google

|
About Me
• PhD in Logic / Types
• Postdoc in Languages
• Now at Google

|
About Me
• PhD in Logic / Types
• Postdoc in Languages
map f (x:xs) = f x : map f xs

• Now at Google

for (x <- xs) f(x)
...
About Me
• PhD in Logic / Types
• Postdoc in Languages
map f (x:xs) = f x : map f xs

• Now at Google

for (x <- xs) f(x)
...
Dart Contributor

|
My Work Involves
• Writing backends
• Writing background jobs (mapreduce)
• Mostly Java, C++

|
I Take for Granted
• Code navigation, completion, static errors
• Libraries / Modules
• Generated documentation
• Reasonab...
I ♥ the Web Platform

|
I ♥ the Web Platform

|
I

Web Development *

* except for fast edit-refresh cycle, that's awesome

|
WAT (h/t Gary Bernhardt)
> [] + {}
[object Object]
> {} + []
0
> {} + {}
NaN

|
WAT - Reloaded
var x = "top-level";
function foo() {
if (true) { var x = "inside-if"; }
console.log(x);
}
foo();

|
WAT - Reloaded
var x = "top-level";
function foo() {
if (true) { var x = "inside-if"; }
console.log(x);
}
foo();
inside-if...
Libraries?

|
Libraries?

|
Libraries?

|
Linker?

|
Linker?

|
Web Development?

|
|
Dart
• Language and Libraries
• Tools
• Virtual Machine
• Compiles to Javascript

|
Targets All Browsers
.dart

|
Targets All Browsers
edit/refresh
.dart

Virtual Machine

|
Targets All Browsers
edit/refresh

deploy
.dart
dart2js
.js

Virtual Machine

|
Alternatives
• CoffeScript & Friends: only improve syntax
• Closure: structure but same semantics
• GWT: good but slow edi...
Dart
• Semantics
• Structure
• Fast edit/refresh cycle

|
Dart in a Nutshell
class Point {
double x, y;
Point(this.x, this.x);
toString() => "($x, $y)";
}
|
Dart in a Nutshell
class Point {

Class-based

double x, y;
Point(this.x, this.x);
toString() => "($x, $y)";
}
|
Dart in a Nutshell
class Point {

Class-based

double x, y;

Optionally typed

Point(this.x, this.x);
toString() => "($x, ...
Dart in a Nutshell
class Point {

Class-based

double x, y;

Optionally typed

Point(this.x, this.x);
toString() => "($x, ...
Dart in a Nutshell
class Point {

Class-based

double x, y;

Optionally typed

Point(this.x, this.x);
toString() => "($x, ...
Dart in a Nutshell
class Point {

Class-based

double x, y;

Optionally typed

Point(this.x, this.x);
toString() => "($x, ...
Clean Unsurprising Semantics

|
Clean Semantics - Examples
• Only true is truthy
• There is no undefined, only null
• No type coercion with ==, +

|
Clean Semantics – Missing Getter
"hello".missing

// ??

|
Clean Semantics – Missing Getter
"hello".missing

// ??

Class 'String' has no instance getter 'missing'.
NoSuchMethodErro...
Clean Semantics – Index out of Range
[][42]

// ??

|
Clean Semantics – Index out of Range
[][42]

// ??

RangeError: 42

|
Clean Semantics – Variable Scope
var x = "top-level";
void foo() {
if (true) { var x = "inside-if"; }
print(x);
}
void mai...
Clean Semantics – Variable Scope
var x = "top-level";
void foo() {
if (true) { var x = "inside-if"; }
print(x);
}
void mai...
Clean Semantics – Scope of this
class App {
App(button) {
button.onClick.listen((e) => this.foo());
}
foo() { … }
}
|
Structure

|
Structure - Libraries
library game;
import 'dart:math';

Module system

class Game { … }
play(Game game) { … }
_secret(Gam...
Structure - Libraries
library game;
import 'dart:math';

Module system

class Game { … }
play(Game game) { … }

Scoped def...
Structure - Libraries
library game;
import 'dart:math';

Module system

class Game { … }
play(Game game) { … }

Scoped def...
Structure - Packages
name: parsers
version: 0.13.6
dependencies:
persistent: '>=0.7.0 <0.8.0'
dev_dependencies:
unittest: ...
Towards a Better Language
• Optional types
• Mixins (class A extends B with C)
• Method cascades (foo..bar(1)..baz(2))
• F...
Towards a Better Language
• Optional types
• Mixins (class A extends B with C)
• Method cascades (foo..bar(1)..baz(2))
• F...
Future Proof APIs
class Point { // now polar coordinates
double angle, radius;
Point(this.angle, this.radius);
…
}
How do ...
Future Proof APIs
class Point { // now polar coordinates
get x => …
set x(value) => …
operator [](int index) => …
toString...
Future Proof APIs
class Point { // now polar coordinates
get x => …
set x(value) => …

Getters / Setters

operator [](int ...
Future Proof APIs
class Point { // now polar coordinates
get x => …
set x(value) => …

Getters / Setters

operator [](int ...
Future Proof APIs
class Point { // now polar coordinates
get x => …
set x(value) => …

Getters / Setters

operator [](int ...
Future Proof APIs
class Point { // now polar coordinates
factory Point(x, y) {
return new Point.polar(…);
}

Factory
const...
Future Proof APIs
class Point { // now polar coordinates
factory Point(x, y) {
return new Point.polar(…);
}

Factory
const...
Not Just a Language
• Modern, consistent library (collections, typed
HTML bindings, futures, streams, ...)
• JS interopera...
Flip It!

|
Flip It!

Snappy UI
Offline playing
|
Flip It!
Validation
required

Snappy UI
Offline playing
|
Code Reuse
import

common.dart
class Board {
Board.decode(str) { … }
String encode() { … }
bool validate() { … }
}

|

ser...
3rd Party Libraries
Bootstrap for Dart
Google APIs client libs
OAuth2 authentication
PostgreSQL driver
Clientside routing
...
3rd Party Libraries

|
Can I Have my Reader Now?

|
Can I Have my Reader Now?

|
The Problem with HTML
• "Widgets" are a bunch of nested divs
• Unique IDs leak all over the place
• CSS leaks to parents /...
The Problem with HTML
• "Widgets" are a bunch of nested divs
• Unique IDs leak all over the place
• CSS leaks to parents /...
The Problem with HTML
• "Widgets" are a bunch of nested divs
• Unique IDs leak all over the place
• CSS leaks to parents /...
MVC Boilerplate
class Model {
StreamController
StreamController
StreamController
StreamController
StreamController
StreamC...
Web Components

|
Web Components
<messages>
<message>
<subject>
Please fill out the TPS report
</subject>
<sent>2012-10-03</sent>
<summary>
...
Custom Elements
<custom-element>
Structure
<div>
<input>
<p>
<span></span>
</p>
</div>

Behavior

Styles

tag.verifyAccoun...
Reusability
Custom
Element
import

HTML Page

import

HTML Page

|

import

HTML Page
Future Proof
• Based on emerging web standards
• Browser vendors interested
• Already partially implemented!

|
|
Polymer: Web Components Today

Polymer.dart

|
Custom Element Declaration
<polymer-element name="my-message">

</polymer-element>

|
Custom Element Declaration
<polymer-element name="my-message">
<template>
<div id="frame">
<b>Subject: </b><content select...
Custom Element Declaration
<polymer-element name="my-message">
<template>
<style> #frame { border: 1px solid black; } </st...
Custom Element Declaration
<polymer-element name="my-message">
<template>
<style> #frame { border: 1px solid black; } </st...
Custom Element Instantiation
<head>
<link rel="import" href="my_message.html">
</head>

|

Import
Custom Element Instantiation
<head>
<link rel="import" href="my_message.html">
</head>

Import

<body>
<my-message>
<span ...
Custom Element Instantiation
<head>
<link rel="import" href="my_message.html">
</head>
<body>
<div id="frame">This won't b...
Custom Element Instantiation

|
Custom Element Instantiation

<my-message>
<span class="subject">Hello</span>
<p>How are you?</p>
</my-message>

|
Custom Element Instantiation

<my-message>
<span class="subject">Hello</span>
<p>How are you?</p>
</my-message>

<div id="...
Custom Element Instantiation

<my-message>
<span class="subject">Hello</span>
<p>How are you?</p>
</my-message>

<div id="...
Custom Element Instantiation
<style>
#frame {
border: 1px solid black;
}
</style>

<div id="frame">
<b>Subject: </b><conte...
Custom Element Instantiation
<style>
#frame {
border: 1px solid black;
}
</style>

<div id="frame">
<b>Subject: </b><conte...
Customwon't be framed</div>
Element Instantiation
<div id="frame">This
<style>
#frame {
border: 1px solid black;
}
</style...
Customwon't be framed</div>
Element Instantiation
<div id="frame">This
<style>
#frame {
border: 1px solid black;
}
</style...
Behavior
@CustomTag('my-message')
class MyMessage extends PolymerElement {
enteredView() {
… this.children …
}
}

|
Behavior
@CustomTag('my-message')
class MyMessage extends PolymerElement {
enteredView() {
… this.children …
}
}

|
Behavior
@CustomTag('my-message')
class MyMessage extends PolymerElement {
enteredView() {
… this.children …
}
}

|
Behavior
@CustomTag('my-message')
class MyMessage extends PolymerElement {
enteredView() {
… this.children …
}
}

|
Behavior
@CustomTag('my-message')
class MyMessage extends PolymerElement {
enteredView() {
… this.children …

Which ones?
...
Shadow DOM
my-message

span

shadow root
div

p
b

"Hello"

"How are
you?"

"Subject:"

|

content

content
Behavior
@CustomTag('my-message')
class MyMessage extends PolymerElement {
enteredView() {

}
}

|
Behavior
@CustomTag('my-message')
class MyMessage extends PolymerElement {
enteredView() {
SpanElement subject = host.quer...
Behavior
@CustomTag('my-message')
class MyMessage extends PolymerElement {
enteredView() {
SpanElement subject = host.quer...
Behavior

Uppercase
3px

|
Data Binding
• Declarative Model-View-*
• Supports two-way bindings out of the box

|
Data Binding
<polymer-element name="click-counter">
<template>
<button on-click="increment">Click Me</button>
<p>You click...
Data Binding
<polymer-element name="click-counter">
<template>
<button on-click="increment">Click Me</button>
<p>You click...
Data Binding
<polymer-element name="click-counter">
<template>
<button on-click="increment">Click Me</button>
<p>You click...
Data Binding
<polymer-element name="click-counter">
<template>
<button on-click="increment">Click Me</button>
<p>You click...
Data Binding
<polymer-element name="click-counter">
<template>
<button on-click="increment">Click Me</button>
<p>You click...
Real World Example
data List<A> = Nil | Cons(A x, List<A> xs)

class List<A> { … }
class Nil<A> extends List<A> { … }
clas...
Real World Example

|
Real World Example
<h2>Define</h2>
<textarea value='{{input}}'>
</textarea>

|
Real World Example

<label>
<input type='checkbox'
checked='{{finalFields}}'>
final fields
</label>

|
Real World Example
<h2>Profit</h2>
<code>
<pre id='generated'>
{{generated}}
</pre>
</code>

|
Real World Example
<h2>Profit</h2>
<code>
<pre id='generated'>
{{generated}}
</pre>
</code>
String get generated {
final c...
Can I have my Reader Now?

|
Can I have my Reader Now?

YES!

|
Bringing Reader Back to Life
• Haskell backend
• Polymer.dart* frontend

* actually its ancestor

|
Bringing Reader Back to Life

|
http://dartlang.org

|
Thanks for the attention!
Follow me on G+ (Paul Brauner)
polux@google.com
https://github.com/polux
Upcoming SlideShare
Loading in …5
×

JAZOON'13 - Paul Brauner - A backend developer meets the web: my Dart experience

32,772 views
32,674 views

Published on

http://guide13.jazoon.com/#/submissions/124

Published in: Education, Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
32,772
On SlideShare
0
From Embeds
0
Number of Embeds
6
Actions
Shares
0
Downloads
20
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

JAZOON'13 - Paul Brauner - A backend developer meets the web: my Dart experience

  1. 1. My Dart Experience Paul Brauner
  2. 2. |
  3. 3. About Me • PhD in Logic / Types • Postdoc in Languages • Now at Google |
  4. 4. About Me • PhD in Logic / Types • Postdoc in Languages • Now at Google |
  5. 5. About Me • PhD in Logic / Types • Postdoc in Languages map f (x:xs) = f x : map f xs • Now at Google for (x <- xs) f(x) |
  6. 6. About Me • PhD in Logic / Types • Postdoc in Languages map f (x:xs) = f x : map f xs • Now at Google for (x <- xs) f(x) |
  7. 7. Dart Contributor |
  8. 8. My Work Involves • Writing backends • Writing background jobs (mapreduce) • Mostly Java, C++ |
  9. 9. I Take for Granted • Code navigation, completion, static errors • Libraries / Modules • Generated documentation • Reasonable performance |
  10. 10. I ♥ the Web Platform |
  11. 11. I ♥ the Web Platform |
  12. 12. I Web Development * * except for fast edit-refresh cycle, that's awesome |
  13. 13. WAT (h/t Gary Bernhardt) > [] + {} [object Object] > {} + [] 0 > {} + {} NaN |
  14. 14. WAT - Reloaded var x = "top-level"; function foo() { if (true) { var x = "inside-if"; } console.log(x); } foo(); |
  15. 15. WAT - Reloaded var x = "top-level"; function foo() { if (true) { var x = "inside-if"; } console.log(x); } foo(); inside-if |
  16. 16. Libraries? |
  17. 17. Libraries? |
  18. 18. Libraries? |
  19. 19. Linker? |
  20. 20. Linker? |
  21. 21. Web Development? |
  22. 22. |
  23. 23. Dart • Language and Libraries • Tools • Virtual Machine • Compiles to Javascript |
  24. 24. Targets All Browsers .dart |
  25. 25. Targets All Browsers edit/refresh .dart Virtual Machine |
  26. 26. Targets All Browsers edit/refresh deploy .dart dart2js .js Virtual Machine |
  27. 27. Alternatives • CoffeScript & Friends: only improve syntax • Closure: structure but same semantics • GWT: good but slow edit/refresh cycle (fixed in upcoming version!) |
  28. 28. Dart • Semantics • Structure • Fast edit/refresh cycle |
  29. 29. Dart in a Nutshell class Point { double x, y; Point(this.x, this.x); toString() => "($x, $y)"; } |
  30. 30. Dart in a Nutshell class Point { Class-based double x, y; Point(this.x, this.x); toString() => "($x, $y)"; } |
  31. 31. Dart in a Nutshell class Point { Class-based double x, y; Optionally typed Point(this.x, this.x); toString() => "($x, $y)"; } |
  32. 32. Dart in a Nutshell class Point { Class-based double x, y; Optionally typed Point(this.x, this.x); toString() => "($x, $y)"; } | Terse syntax
  33. 33. Dart in a Nutshell class Point { Class-based double x, y; Optionally typed Point(this.x, this.x); toString() => "($x, $y)"; } | Terse syntax
  34. 34. Dart in a Nutshell class Point { Class-based double x, y; Optionally typed Point(this.x, this.x); toString() => "($x, $y)"; } | Terse syntax
  35. 35. Clean Unsurprising Semantics |
  36. 36. Clean Semantics - Examples • Only true is truthy • There is no undefined, only null • No type coercion with ==, + |
  37. 37. Clean Semantics – Missing Getter "hello".missing // ?? |
  38. 38. Clean Semantics – Missing Getter "hello".missing // ?? Class 'String' has no instance getter 'missing'. NoSuchMethodError : method not found: 'missing' Receiver: "hello" Arguments: [] |
  39. 39. Clean Semantics – Index out of Range [][42] // ?? |
  40. 40. Clean Semantics – Index out of Range [][42] // ?? RangeError: 42 |
  41. 41. Clean Semantics – Variable Scope var x = "top-level"; void foo() { if (true) { var x = "inside-if"; } print(x); } void main() { foo(); } // ?? |
  42. 42. Clean Semantics – Variable Scope var x = "top-level"; void foo() { if (true) { var x = "inside-if"; } print(x); } void main() { foo(); } // ?? top-level |
  43. 43. Clean Semantics – Scope of this class App { App(button) { button.onClick.listen((e) => this.foo()); } foo() { … } } |
  44. 44. Structure |
  45. 45. Structure - Libraries library game; import 'dart:math'; Module system class Game { … } play(Game game) { … } _secret(Game game) { … } |
  46. 46. Structure - Libraries library game; import 'dart:math'; Module system class Game { … } play(Game game) { … } Scoped definitions _secret(Game game) { … } |
  47. 47. Structure - Libraries library game; import 'dart:math'; Module system class Game { … } play(Game game) { … } Scoped definitions _secret(Game game) { … } | Private definition
  48. 48. Structure - Packages name: parsers version: 0.13.6 dependencies: persistent: '>=0.7.0 <0.8.0' dev_dependencies: unittest: any |
  49. 49. Towards a Better Language • Optional types • Mixins (class A extends B with C) • Method cascades (foo..bar(1)..baz(2)) • Future proof APIs |
  50. 50. Towards a Better Language • Optional types • Mixins (class A extends B with C) • Method cascades (foo..bar(1)..baz(2)) • Future proof APIs |
  51. 51. Future Proof APIs class Point { // now polar coordinates double angle, radius; Point(this.angle, this.radius); … } How do we prevent clients from breaking? |
  52. 52. Future Proof APIs class Point { // now polar coordinates get x => … set x(value) => … operator [](int index) => … toString([bool asJson]) => … } |
  53. 53. Future Proof APIs class Point { // now polar coordinates get x => … set x(value) => … Getters / Setters operator [](int index) => … toString([bool asJson]) => … } |
  54. 54. Future Proof APIs class Point { // now polar coordinates get x => … set x(value) => … Getters / Setters operator [](int index) => … toString([bool asJson]) => … } | Operator overriding
  55. 55. Future Proof APIs class Point { // now polar coordinates get x => … set x(value) => … Getters / Setters operator [](int index) => … Operator overriding toString([bool asJson]) => … } | Optional arguments
  56. 56. Future Proof APIs class Point { // now polar coordinates factory Point(x, y) { return new Point.polar(…); } Factory constructors Point.polar(angle, radius) { … } } |
  57. 57. Future Proof APIs class Point { // now polar coordinates factory Point(x, y) { return new Point.polar(…); } Factory constructors Point.polar(angle, radius) { … } } | Named constructors
  58. 58. Not Just a Language • Modern, consistent library (collections, typed HTML bindings, futures, streams, ...) • JS interoperability • Server-side programming |
  59. 59. Flip It! |
  60. 60. Flip It! Snappy UI Offline playing |
  61. 61. Flip It! Validation required Snappy UI Offline playing |
  62. 62. Code Reuse import common.dart class Board { Board.decode(str) { … } String encode() { … } bool validate() { … } } | server.dart import client.dart
  63. 63. 3rd Party Libraries Bootstrap for Dart Google APIs client libs OAuth2 authentication PostgreSQL driver Clientside routing Web Server |
  64. 64. 3rd Party Libraries |
  65. 65. Can I Have my Reader Now? |
  66. 66. Can I Have my Reader Now? |
  67. 67. The Problem with HTML • "Widgets" are a bunch of nested divs • Unique IDs leak all over the place • CSS leaks to parents / children |
  68. 68. The Problem with HTML • "Widgets" are a bunch of nested divs • Unique IDs leak all over the place • CSS leaks to parents / children |
  69. 69. The Problem with HTML • "Widgets" are a bunch of nested divs • Unique IDs leak all over the place • CSS leaks to parents / children |
  70. 70. MVC Boilerplate class Model { StreamController StreamController StreamController StreamController StreamController StreamController StreamController _onCurrentBoardChanged = new StreamController(); _onPreviousBoardChanged = new StreamController(); _onCurrentPathChanged = new StreamController(); _onPreviousPathChanged = new StreamController(); _onStateChanged = new StreamController(); _onUserInfoChanged = new StreamController(); _onSignInStatusChanged = new StreamController(); void _initStreams() { onCurrentBoardChanged = _onCurrentBoardChanged.stream.asBroadcastStream(); onPreviousBoardChanged = _onPreviousBoardChanged.stream.asBroadcastStream(); onCurrentPathChanged = _onCurrentPathChanged.stream.asBroadcastStream(); onPreviousPathChanged = _onPreviousPathChanged.stream.asBroadcastStream(); onStateChanged = _onStateChanged.stream.asBroadcastStream(); onUserInfoChanged = _onUserInfoChanged.stream.asBroadcastStream(); onSignInStatusChanged = _onSignInStatusChanged.stream.asBroadcastStream(); } void _currentBoardChanged() { _onCurrentBoardChanged.add(null); } … } |
  71. 71. Web Components |
  72. 72. Web Components <messages> <message> <subject> Please fill out the TPS report </subject> <sent>2012-10-03</sent> <summary> I'm going to have to ask you to come in... </summary> </message> <message> <subject> Reminder: fill out that TPS report! </subject> <sent>2012-10-04</sent> <summary> It's been 24 hours... </summary> </message> ... </messages> |
  73. 73. Custom Elements <custom-element> Structure <div> <input> <p> <span></span> </p> </div> Behavior Styles tag.verifyAccount(); <style> p { color: red; } </style> |
  74. 74. Reusability Custom Element import HTML Page import HTML Page | import HTML Page
  75. 75. Future Proof • Based on emerging web standards • Browser vendors interested • Already partially implemented! |
  76. 76. |
  77. 77. Polymer: Web Components Today Polymer.dart |
  78. 78. Custom Element Declaration <polymer-element name="my-message"> </polymer-element> |
  79. 79. Custom Element Declaration <polymer-element name="my-message"> <template> <div id="frame"> <b>Subject: </b><content select=".subject"></content> <content select="p"></content> </div> Structure </template> </polymer-element> |
  80. 80. Custom Element Declaration <polymer-element name="my-message"> <template> <style> #frame { border: 1px solid black; } </style> Style <div id="frame"> <b>Subject: </b><content select=".subject"></content> <content select="p"></content> </div> Structure </template> </polymer-element> |
  81. 81. Custom Element Declaration <polymer-element name="my-message"> <template> <style> #frame { border: 1px solid black; } </style> Style <div id="frame"> <b>Subject: </b><content select=".subject"></content> <content select="p"></content> </div> Structure </template> <script type="application/dart" src="my_message.dart"></script> </polymer-element> Behavior |
  82. 82. Custom Element Instantiation <head> <link rel="import" href="my_message.html"> </head> | Import
  83. 83. Custom Element Instantiation <head> <link rel="import" href="my_message.html"> </head> Import <body> <my-message> <span class="subject">Hello</span> <p>How are you?</p> </my-message> </body> | Instantiation
  84. 84. Custom Element Instantiation <head> <link rel="import" href="my_message.html"> </head> <body> <div id="frame">This won't be framed</div> <my-message> <span class="subject">Hello</span> <p>How are you?</p> </my-message> </body> | Import Encapsulation Instantiation
  85. 85. Custom Element Instantiation |
  86. 86. Custom Element Instantiation <my-message> <span class="subject">Hello</span> <p>How are you?</p> </my-message> |
  87. 87. Custom Element Instantiation <my-message> <span class="subject">Hello</span> <p>How are you?</p> </my-message> <div id="frame"> <b>Subject: </b><content select=".subject"></content> <content select="p"></content> </div> |
  88. 88. Custom Element Instantiation <my-message> <span class="subject">Hello</span> <p>How are you?</p> </my-message> <div id="frame"> <b>Subject: </b><content select=".subject"></content> <content select="p"></content> </div> |
  89. 89. Custom Element Instantiation <style> #frame { border: 1px solid black; } </style> <div id="frame"> <b>Subject: </b><content select=".subject"></content> <content select="p"></content> </div> |
  90. 90. Custom Element Instantiation <style> #frame { border: 1px solid black; } </style> <div id="frame"> <b>Subject: </b><content select=".subject"></content> <content select="p"></content> </div> |
  91. 91. Customwon't be framed</div> Element Instantiation <div id="frame">This <style> #frame { border: 1px solid black; } </style> <div id="frame"> <b>Subject: </b><content select=".subject"></content> <content select="p"></content> </div> |
  92. 92. Customwon't be framed</div> Element Instantiation <div id="frame">This <style> #frame { border: 1px solid black; } </style> <div id="frame"> <b>Subject: </b><content select=".subject"></content> <content select="p"></content> </div> |
  93. 93. Behavior @CustomTag('my-message') class MyMessage extends PolymerElement { enteredView() { … this.children … } } |
  94. 94. Behavior @CustomTag('my-message') class MyMessage extends PolymerElement { enteredView() { … this.children … } } |
  95. 95. Behavior @CustomTag('my-message') class MyMessage extends PolymerElement { enteredView() { … this.children … } } |
  96. 96. Behavior @CustomTag('my-message') class MyMessage extends PolymerElement { enteredView() { … this.children … } } |
  97. 97. Behavior @CustomTag('my-message') class MyMessage extends PolymerElement { enteredView() { … this.children … Which ones? } } |
  98. 98. Shadow DOM my-message span shadow root div p b "Hello" "How are you?" "Subject:" | content content
  99. 99. Behavior @CustomTag('my-message') class MyMessage extends PolymerElement { enteredView() { } } |
  100. 100. Behavior @CustomTag('my-message') class MyMessage extends PolymerElement { enteredView() { SpanElement subject = host.query('.subject'); subject.text = subject.text.toUpperCase(); } } | DOM
  101. 101. Behavior @CustomTag('my-message') class MyMessage extends PolymerElement { enteredView() { SpanElement subject = host.query('.subject'); subject.text = subject.text.toUpperCase(); DivElement frame = shadowRoot.query('#frame'); frame.style.borderWidth = '3px'; } } | DOM Shadow DOM
  102. 102. Behavior Uppercase 3px |
  103. 103. Data Binding • Declarative Model-View-* • Supports two-way bindings out of the box |
  104. 104. Data Binding <polymer-element name="click-counter"> <template> <button on-click="increment">Click Me</button> <p>You clicked the button {{count}} times.</p> </template> </polymer-element> |
  105. 105. Data Binding <polymer-element name="click-counter"> <template> <button on-click="increment">Click Me</button> <p>You clicked the button {{count}} times.</p> </template> </polymer-element> |
  106. 106. Data Binding <polymer-element name="click-counter"> <template> <button on-click="increment">Click Me</button> <p>You clicked the button {{count}} times.</p> </template> </polymer-element> |
  107. 107. Data Binding <polymer-element name="click-counter"> <template> <button on-click="increment">Click Me</button> <p>You clicked the button {{count}} times.</p> </template> <script src="click_counter.dart" type="…" ></script> </polymer-element> @CustomTag('click-counter') class ClickCounterElement extends PolymerElement { @observable int count = 0; void increment(Event e, var detail, Node target) { count += 1; } } |
  108. 108. Data Binding <polymer-element name="click-counter"> <template> <button on-click="increment">Click Me</button> <p>You clicked the button {{count}} times.</p> </template> <script src="click_counter.dart" type="…" ></script> </polymer-element> @CustomTag('click-counter') class ClickCounterElement extends PolymerElement { @observable int count = 0; void increment(Event e, var detail, Node target) { count += 1; } } |
  109. 109. Real World Example data List<A> = Nil | Cons(A x, List<A> xs) class List<A> { … } class Nil<A> extends List<A> { … } class Cons<A> extends List<A> { … } |
  110. 110. Real World Example |
  111. 111. Real World Example <h2>Define</h2> <textarea value='{{input}}'> </textarea> |
  112. 112. Real World Example <label> <input type='checkbox' checked='{{finalFields}}'> final fields </label> |
  113. 113. Real World Example <h2>Profit</h2> <code> <pre id='generated'> {{generated}} </pre> </code> |
  114. 114. Real World Example <h2>Profit</h2> <code> <pre id='generated'> {{generated}} </pre> </code> String get generated { final config = new Config(finalFields, … ); return generate(input, config); } |
  115. 115. Can I have my Reader Now? |
  116. 116. Can I have my Reader Now? YES! |
  117. 117. Bringing Reader Back to Life • Haskell backend • Polymer.dart* frontend * actually its ancestor |
  118. 118. Bringing Reader Back to Life |
  119. 119. http://dartlang.org |
  120. 120. Thanks for the attention! Follow me on G+ (Paul Brauner) polux@google.com https://github.com/polux

×