Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
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

33,031 views

Published on

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

Published in: Education, Technology
  • Be the first to comment

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

×