JAZOON'13 - Paul Brauner - A backend developer meets the web: my Dart experience
Upcoming SlideShare
Loading in...5
×
 

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

on

  • 13,607 views

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

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

Statistics

Views

Total Views
13,607
Views on SlideShare
13,432
Embed Views
175

Actions

Likes
1
Downloads
19
Comments
0

6 Embeds 175

http://guide.jazoon.com 83
http://jazoonvote.appspot.com 57
https://twitter.com 31
http://guide13.jazoon.com 2
http://localhost 1
http://plus.url.google.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

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

  • 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 • Reasonable performance |
  • 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 edit/refresh cycle (fixed in upcoming version!) |
  • 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, $y)"; } |
  • Dart in a Nutshell class Point { Class-based double x, y; Optionally typed Point(this.x, this.x); toString() => "($x, $y)"; } | Terse syntax
  • Dart in a Nutshell class Point { Class-based double x, y; Optionally typed Point(this.x, this.x); toString() => "($x, $y)"; } | Terse syntax
  • Dart in a Nutshell class Point { Class-based double x, y; Optionally typed Point(this.x, this.x); toString() => "($x, $y)"; } | Terse syntax
  • 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'. NoSuchMethodError : method not found: 'missing' Receiver: "hello" Arguments: [] |
  • 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 main() { foo(); } // ?? |
  • Clean Semantics – Variable Scope var x = "top-level"; void foo() { if (true) { var x = "inside-if"; } print(x); } void main() { foo(); } // ?? top-level |
  • 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(Game game) { … } |
  • Structure - Libraries library game; import 'dart:math'; Module system class Game { … } play(Game game) { … } Scoped definitions _secret(Game game) { … } |
  • Structure - Libraries library game; import 'dart:math'; Module system class Game { … } play(Game game) { … } Scoped definitions _secret(Game game) { … } | Private definition
  • Structure - Packages name: parsers version: 0.13.6 dependencies: persistent: '>=0.7.0 <0.8.0' dev_dependencies: unittest: any |
  • Towards a Better Language • Optional types • Mixins (class A extends B with C) • Method cascades (foo..bar(1)..baz(2)) • Future proof APIs |
  • Towards a Better Language • Optional types • Mixins (class A extends B with C) • Method cascades (foo..bar(1)..baz(2)) • Future proof APIs |
  • Future Proof APIs class Point { // now polar coordinates double angle, radius; Point(this.angle, this.radius); … } How do we prevent clients from breaking? |
  • Future Proof APIs class Point { // now polar coordinates get x => … set x(value) => … operator [](int index) => … toString([bool asJson]) => … } |
  • Future Proof APIs class Point { // now polar coordinates get x => … set x(value) => … Getters / Setters operator [](int index) => … toString([bool asJson]) => … } |
  • Future Proof APIs class Point { // now polar coordinates get x => … set x(value) => … Getters / Setters operator [](int index) => … toString([bool asJson]) => … } | Operator overriding
  • 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
  • Future Proof APIs class Point { // now polar coordinates factory Point(x, y) { return new Point.polar(…); } Factory constructors Point.polar(angle, radius) { … } } |
  • Future Proof APIs class Point { // now polar coordinates factory Point(x, y) { return new Point.polar(…); } Factory constructors Point.polar(angle, radius) { … } } | Named constructors
  • Not Just a Language • Modern, consistent library (collections, typed HTML bindings, futures, streams, ...) • JS interoperability • Server-side programming |
  • 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() { … } } | server.dart import client.dart
  • 3rd Party Libraries Bootstrap for Dart Google APIs client libs OAuth2 authentication PostgreSQL driver Clientside routing Web Server |
  • 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 / children |
  • The Problem with HTML • "Widgets" are a bunch of nested divs • Unique IDs leak all over the place • CSS leaks to parents / children |
  • The Problem with HTML • "Widgets" are a bunch of nested divs • Unique IDs leak all over the place • CSS leaks to parents / children |
  • 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); } … } |
  • Web Components |
  • 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> |
  • Custom Elements <custom-element> Structure <div> <input> <p> <span></span> </p> </div> Behavior Styles tag.verifyAccount(); <style> p { color: red; } </style> |
  • 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=".subject"></content> <content select="p"></content> </div> Structure </template> </polymer-element> |
  • 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> |
  • 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 |
  • 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 class="subject">Hello</span> <p>How are you?</p> </my-message> </body> | Instantiation
  • 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
  • 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="frame"> <b>Subject: </b><content select=".subject"></content> <content select="p"></content> </div> |
  • 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> |
  • 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> |
  • 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> |
  • 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> |
  • 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> |
  • 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.query('.subject'); subject.text = subject.text.toUpperCase(); } } | DOM
  • 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
  • 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 clicked the button {{count}} times.</p> </template> </polymer-element> |
  • 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> |
  • 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> |
  • 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; } } |
  • 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; } } |
  • 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> { … } |
  • 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 config = new Config(finalFields, … ); return generate(input, config); } |
  • 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