Ein Ersatz für Javascript?
Transcription
Ein Ersatz für Javascript?
Seminar SS13 von Krzysztof Rahn Dart Ein Ersatz für Javascript? Inhalt ● ● ● ● ● ● ● ● ● Dart allgemein Tools Erste Beispiele Dart Ausführung Funktionalitäten Sprachkonzepte Praktischer Einsatz Performance Fazit Dart allgemein: Warum entwickelt Google Dart? ● Der Code wird immer.. ○ ..größer ○ ..komplexer ○ ..unübersichtlicher ● Gmail hat ca. 443.000 JS Lines Of Code! ● Große Web Anwendungen machen zu viel Aufwand Dart allgemein: Warum entwickelt Google Dart? ● Probleme mit JavaScript ○ keine Namenräume ○ keine Sichtbarkeits Kontrolle ○ kein Typsystem Dart allgemein: Warum entwickelt Google Dart? ● ● ● ● ● ● Google will Webentwicklung verbessern Es soll praktisch sein Leicht zu erlernen Die Apps sollen schnell laden Bessere Performance Bessere Produktivität Dart allgemein: Warum entwickelt Google Dart? ● ● ● ● ● ● Google will Webentwicklung verbessern Es soll praktisch sein Leicht zu erlernen Die Apps sollen schnell laden Bessere Performance Bessere Produktivität Ziel: App Entwicklern zu helfen Komplexe und sehr Performante Client Apps zu schreiben für das Moderne Internet. Dart allgemein: Das Dart Team ● Lars Bak ○ Entwickelt die HotSpot Java VM ○ Leitet die Entwicklung von V8 JavaScript VM für Google Chrome ○ 18 Software Patente im Bereich der VMs Dart allgemein: Das Dart Team ● Gilad Bracha ○ co-author Java Language Specification ○ co-author Java Virtual Machine Specification ○ Hat Java populär gemacht Tools: ● ● ● ● ● ● Virtual Machine (VM) Dart-to-Javascript compiler Dartboard - try.dartlang.org Dartium Dart Editor SDK ○ dart:html ■ DOM manipulation ■ JQuery ○ dart:async ■ Ajax ○ dart:json ■ JSON ○ ... Beispiel Quellcode (1) extern eingebunden hi.dart: import 'dart:html'; main() { document.query('#status').text = 'Hi, Dart'; //document.getElementById('status').innerHTML = 'Hi, JS'; } hi.html: <!DOCTYPE html> <html><body> <h2 id="status"></h2> <script type="application/dart" src="hi.dart"> </script> <script type="text/javascript" src="dart.js"> </script> </body></html> Beispiel Quellcode (2) Funktionen, String Interpolation, Funk. Block send (msg, to, from, [rate='First Class']) { return '$from said $msg to $to via $rate'; } main() => print(send('hello', 'Seth', 'Bob')); null Oder: send (msg, to, from, [rate='First Class']) => '$from said $msg to $to via $rate'; main() { print(send('hello', 'Seth', 'Bob')); } // return Beispiel Quellcode (2) Funktionen, String Interpolation, Funk. Block Dart: send (msg, to, from, [rate='First Class']) { return '$from said $msg to $to via $rate'; } main() => print(send('hello', 'Seth', 'Bob')); // return null Javascript: function send (msg, to, from, rate) { rate = (typeof rate==="undefined")?"First Class": rate; return from+' said '+msg+' to '+to+' via '+rate; } console.log(send('hello', 'Seth', 'Bob')); Beispiel Quellcode (3) Bibliotheken, Klassen, Objekte import 'dart:math' as Math; class Point { Point(this.x, this.y); distanceTo(other) { var dx = x - other.x; var dy = y - other.y; return Math.sqrt(dx * dx + dy * dy); } var x, y; } main() { var p = new Point(2, 3); var q = new Point(3, 4); print('distance from p to q = ${p.distanceTo(q)}'); } Dart Execution dart2js Kompilieren Output JS Quellcode Interpretiert JavaScript Engine Dart Quellcode Interpretiert Interpretiert. Direkt => kein Bytecode Dart VM --generate-scriptsnapshot Erstellt Snapshot Lädt Dart VM Funktionalitäten: Snapshots ● Für schnelles starten der Apps (ca. 10x) ● Wird z.B. für die Bibliotheken benutzt ● Client: 2. Aufruf lädt den Snapshot vom Browser Cache ● Ein Token-stream in Binärformat Snapshot erstellen: dart --generate-script-snapshot=HalloDart.ss HalloDart. dart Snapshot benutzen: dart HalloDart.ss Funktionalitäten: Runtime Modes ● Production mode ○ Standard Modus ○ Optimiert auf Geschwindigkeit ○ Ignoriert Asserts ● Checked mode ○ Entwickler freundlich ○ Typen-uberprüfung ○ dart --checked test.dart Sprachkonzepte: Objektorientiert ● Alles ist ein Objekt ● eine rein Objektorientierte Sprache ○ wie in Javascript, Smalltalk, Ruby, Scala usw. ○ 42.7.round() // 43 ● kein Autoboxing ● keine versteckte Typumwandlungen ○ var test = 3 + "4"; // Dart: Fehler! / JS: OK > "34" Sprachkonzepte: Optionale Typen ● Static typing ○ Typprüfung zur Übersetzungszeit ○ Weniger Fehler, sicher ● Dynamic typing ○ Flexibel ○ Leicht nutzbar Sprachkonzepte: Optionale Typen class Person {} class Customer extends Person { buy() {print("bought");} } main() { Person p = new Customer(); p.buy(); } Sprachkonzepte: Optionale Typen class Person {} class Customer extends Person { buy() {print("bought");} } main() { Person p = new Customer(); p.buy(); } ● Java: Fehler! buy() kein Member von Person. Sprachkonzepte: Optionale Typen class Person {} class Customer extends Person { buy() {print("bought");} } main() { Person p = new Customer(); p.buy(); } ● Java: Fehler! buy() kein Member von Person. ● Javascript: OK. p ist jetzt ein Customer. Sprachkonzepte: Optionale Typen class Person {} class Customer extends Person { buy() {print("bought");} } main() { Person p = new Customer(); p.buy(); } ● Java: Fehler! buy() kein Member von Person. ● Javascript: OK. p ist jetzt ein Customer. ● Dart: OK, aber mit Warnung. In Checked Mode: Fehler! Sprachkonzepte: Optionale Typen ● Static typing ○ Typprüfung zur Übersetzungszeit ○ Weniger Fehler, sicher ● Dynamic typing ○ Flexibel ○ Leicht nutzbar ● Optionale Typen ○ Kompromiss zwischen Static & Dynamic typing ○ Sicherheit der Statischen typisierung ○ Flexibilität der Dynamischen typisierung Sprachkonzepte: Optionale Typen Typname Wertebereic h Nummer num int or double Integer int kein Limit Double double 64bit IEEE 754 Boolean bool true or false String String UTF-16 Listen List<dynamic> Maps Map<dynamic, dynamic> ... ... ... Sprachkonzepte: Optionale Typen if (1) { // In Javascript -> true } else { // In Dart -> false } if ([0]) { // In Javascript -> true } ● "false" in Javascript ○ false, null, undefined, "", -0, 0, NaN Sprachkonzepte: Optionale Typen ● Wichtig: ○ Typen als Dokumentation für Entwickler ○ Typen als Dokumentation für die Tools (type checks) ○ Typen beeinflussen nicht das Programm Sprachkonzepte: Closures ● Funktion mit Zugriff auf den Erstellungskontext JavaScript: function fibonacci() { var x = 0; var y = 1 var z; Dart: fibonacci() { int x = 0; int y = 1; int z; return function() { z = x; x = y; y = z+y; return y - x; } return () { z = x; x = y; y = z+y; return y - x; }; } } var nextfib = fibonacci(); console.log( nextfib() ); var nextfib = fibonacci(); print( nextfib() ); Sprachkonzepte: Klassen ● public, private ● toString, NoSuchMethod Javascript: Dart: function Apple (type) { this.type = type; this.color = "red"; } class Apple { String type; String color; Apple (this.type); Apple.prototype.getInfo = function() { return this.color + ' ' + this.type + ' apple'; }; var apple = new Apple('Mac'); apple.color = 'reddish'; alert( apple.getInfo() ); getInfo () { return '$color $type' ' apple'; } } var apple = new Apple('Mac'); apple.color = 'green'; window.alert(apple.getInfo()); Sprachkonzepte: Vererbung ● Einfachvererbung ● Implicite Interfaces ● Mixins ○ Delta zwischen der Klasse und der Superklasse Sprachkonzepte: Vererbung ● Einfachvererbung ● Implicite Interfaces ● Mixins ○ Delta zwischen der Klasse und der Superklasse abstract class Shape { num perimeter(); } class Rectangle implements Shape { final num height, width; Rectangle(this.height, this.width); num perimeter() => 2*height + 2*width; } class Square extends Rectangle { Square(num size) : super(size, size); } Sprachkonzepte: Mixins class firstmixin { var number = 2; printNum1() => print( "FirstNum: $number" ); } class secondmixin{ var number = 5; printNum2() => print( "SecondNum: $number" ); } class Point extends Object with firstmixin, secondmixin { var number = 8; printNumber() => printNum1(); } Sprachkonzepte: Nebenläufigkeit mit Isolates ● Keine shared-memory threads ● Programme sind aus Isolates gebaut ● Isolates sind wie Actoren ○ Heap und Stack getrennt ○ Kommunikation über Ports Sprachkonzepte: Vergleich Funktionalität Dart Java JavaScript Dynamisch (Optional) Statisch Dynamisch First-Class Funktionen Ja mit Anonymen Funktionen Ja Closures Ja Ja Ja Klassen Ja, Einfach Ja, Einfach Prototyp-basierend Ja, Mehrfach Ja, Mehrfach Nein Ja, mit Isolates Ja, mit Threads Ja, mit HTML5 web workers Typsystem Interfaces Nebenläufigkeit Praktischer Einsatz: DOM manipulation Javascript: getElementsById() getElementsByTagName() getElementsByName() getElementsByClassName() querySelector() querySelectorAll() document.links document.images document.forms document.scripts formElement.elements selectElement.options Dart: query() queryAll() Praktischer Einsatz: DOM manipulation Javascript: elem.getElementById('foo'); elem.getElementsByTagName('div'); elem.getElementsByName('foo'); elem.getElementsByClassName('foo'); elem.querySelector('.foo .bar'); elem.querySelectorAll('.foo .bar'); Dart: elem.query('#foo'); elem.queryAll('div'); elem.queryAll('[name="foo"]'); elem.queryAll('.foo'); elem.query('.foo .bar'); elem.queryAll('.foo .bar'); Praktischer Einsatz: Popup Fenster öffnen <input type= "submit" id="spbutton" value="ShowPopup" > Javascript: var button = document.getElementById( 'spbutton' ); button.onclick = function(){ window.open( 'http://www.example.com/' ); }; Dart: InputElement button = query( '#spbutton' ); button.onClick.listen((Event e) { window.open( 'http://www.example.com/' ); }); Praktischer Einsatz: Input auslesen, DOM manipulieren <p> From local storage: <output id= "username-output" ></output> </p> <label for= "username" >Username:</label> <input type= "text" name="username" id="username" > <input type= "submit" id="save" value="Save"> InputElement username = query( '#username' ); InputElement submit = query( '#save'); Element output = query( '#username-output' ); submit.onClick.listen((Event e) { output.text = username.value; }); Performance: Richards ● OS kernel simulation benchmark ● Schwerpunkt: ○ Objekt zugriffe ○ Aufruf von Funktionen und Methoden Dart VM V8 dart2js Fazit ● Dart ist ... (vergliechen zu JS) ○ ○ ○ ○ ○ ○ ○ ○ ..eleganter (class vs prototypes) ..lesbarer (typen) ..für Mainstream ..auch für Komplexe Apps ..schneller weniger Fehler ..Multithreading fähig ..leichter zu lernen ○ ..noch etwas Instabil ○ API ändert sich ständig ○ ..nicht so stark verbreitet Vielen Dank für die Aufmerksamkeit!