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!