Fay Haskell auf Client-Seite. von Alexander Mills

of 173
All materials on our website are shared by users. If you have any questions about copyright issues, please report us to resolve them. We are always happy to assist you.
Categories
Published
Fay Haskell auf Client-Seite von Alexander Mills Inhalt Was ist Fay? Inhalt Was ist Fay? Motivation Inhalt Was ist Fay? Motivation Wie arbeitet Fay? Inhalt Was ist Fay? Motivation Wie arbeitet Fay? FFI
Fay Haskell auf Client-Seite von Alexander Mills Inhalt Was ist Fay? Inhalt Was ist Fay? Motivation Inhalt Was ist Fay? Motivation Wie arbeitet Fay? Inhalt Was ist Fay? Motivation Wie arbeitet Fay? FFI Inhalt Was ist Fay? Motivation Wie arbeitet Fay? FFI Codebeispiele Inhalt Was ist Fay? Motivation Wie arbeitet Fay? FFI Codebeispiele Was kann Fay nicht? Inhalt Was ist Fay? Motivation Wie arbeitet Fay? FFI Codebeispiele Was kann Fay nicht? Fazit Das JavaScript-Problem Das JavaScript-Problem JavaScript sucks! Das JavaScript-Problem JavaScript sucks! versus We need JavaScript! Das JavaScript-Problem Nachteile: Vorteile: Das JavaScript-Problem Nachteile: schwach typisiert Vorteile: Das JavaScript-Problem Nachteile: schwach typisiert keine Modularisierung Vorteile: Das JavaScript-Problem Nachteile: schwach typisiert keine Modularisierung späte Bindung Vorteile: Das JavaScript-Problem Nachteile: schwach typisiert keine Modularisierung späte Bindung automatische Typkonversion Vorteile: Das JavaScript-Problem Nachteile: schwach typisiert keine Modularisierung späte Bindung automatische Typkonversion keine statischen Typen Vorteile: Das JavaScript-Problem Nachteile: schwach typisiert keine Modularisierung späte Bindung automatische Typkonversion keine statischen Typen Vorteile: Plattform für Webdevelopment Das JavaScript-Problem Nachteile: schwach typisiert keine Modularisierung späte Bindung automatische Typkonversion keine statischen Typen Vorteile: Plattform für Webdevelopment Unterstützung für alle aktuellen Betriebssysteme und Browser Die Lösung Die Lösung Compiler Die Lösung Compiler Existierende Sprache, die nicht die Probleme von JavaScript hat, nach JavaScript übersetzen. Die Lösung Compiler Existierende Sprache, die nicht die Probleme von JavaScript hat, nach JavaScript übersetzen. Sprache der Wahl: Die Lösung Compiler Existierende Sprache, die nicht die Probleme von JavaScript hat, nach JavaScript übersetzen. Sprache der Wahl: Haskell Die Lösung Compiler Existierende Sprache, die nicht die Probleme von JavaScript hat, nach JavaScript übersetzen. Sprache der Wahl: Haskell Quelle: haskell.org Was ist Fay? Was ist Fay? Haskell zu JavaScript Compiler Was ist Fay? Haskell zu JavaScript Compiler Unterstützt eine Untermenge von Haskell Was ist Fay? Haskell zu JavaScript Compiler Unterstützt eine Untermenge von Haskell Setzt Eigenschaften von Haskell um Was ist Fay? Haskell zu JavaScript Compiler Unterstützt eine Untermenge von Haskell Setzt Eigenschaften von Haskell um Statische Typisierung Was ist Fay? Haskell zu JavaScript Compiler Unterstützt eine Untermenge von Haskell Setzt Eigenschaften von Haskell um Statische Typisierung Lazy Evaluation Was ist Fay? Haskell zu JavaScript Compiler Unterstützt eine Untermenge von Haskell Setzt Eigenschaften von Haskell um Statische Typisierung Lazy Evaluation Bietet Support für Grunddatentypen (Double, String, Integer, Boolean, etc.) Was ist Fay? Haskell zu JavaScript Compiler Unterstützt eine Untermenge von Haskell Setzt Eigenschaften von Haskell um Statische Typisierung Lazy Evaluation Bietet Support für Grunddatentypen (Double, String, Integer, Boolean, etc.) Möglichkeit JavaScript-Funktionalität (z.b. Zugriff auf DOM Struktur) zu benutzen mittels FFI Arbeitsweise Wie kompiliert Fay? Arbeitsweise: Grundschema Aufbau des zu erzeugenden JavaScript-Codes: Arbeitsweise: Grundschema Aufbau des zu erzeugenden JavaScript-Codes: Fay-Laufzeit Arbeitsweise: Grundschema Aufbau des zu erzeugenden JavaScript-Codes: Fay-Laufzeit Listen, Monaden, arithmetische Operationen Arbeitsweise: Grundschema Aufbau des zu erzeugenden JavaScript-Codes: Fay-Laufzeit Listen, Monaden, arithmetische Operationen Thunks für Lazy Evaluation Arbeitsweise: Grundschema Aufbau des zu erzeugenden JavaScript-Codes: Fay-Laufzeit Listen, Monaden, arithmetische Operationen Thunks für Lazy Evaluation Haskell Prelude Arbeitsweise: Grundschema Aufbau des zu erzeugenden JavaScript-Codes: Fay-Laufzeit Listen, Monaden, arithmetische Operationen Thunks für Lazy Evaluation Haskell Prelude Das eigentliche Programm Arbeitsweise: Grundschema Aufbau des zu erzeugenden JavaScript-Codes: Klassenkonstruktor mit Inhalt: Fay-Laufzeit Listen, Monaden, arithmetische Operationen Thunks für Lazy Evaluation Haskell Prelude Das eigentliche Programm Arbeitsweise: Grundschema Aufbau des zu erzeugenden JavaScript-Codes: Klassenkonstruktor mit Inhalt: Fay-Laufzeit Listen, Monaden, arithmetische Operationen Thunks für Lazy Evaluation Haskell Prelude Das eigentliche Programm Erzeugen einer Instanz der Klasse und Aufruf der Hauptfunktion Arbeitsweise: Grundschema Namenskonvention: Modulname$Funktionsname Arbeitsweise: Grundschema Namenskonvention: Modulname$Funktionsname Ist im Haskellcode kein Modulname festgelegt = Main Arbeitsweise: Grundschema Namenskonvention: Modulname$Funktionsname Ist im Haskellcode kein Modulname festgelegt = Main Beispiele: Fay$$add, Prelude$id, Main$main Arbeitsweise: Grundschema var Main = function() { /* Fay Runtime */ /* Prelude */ /* Mein Programm */ }; var main = new Main(); main.main$main(); Arbeitsweise: Grundschema var Main = function() { /* Fay Runtime */ /* Prelude */ /* Mein Programm */ }; var main = new Main(); main._(main.main$main); Arbeitsweise: Thunks Arbeitsweise: Thunks Thunks sind (noch) nicht berechnete Werte. Arbeitsweise: Thunks Thunks sind (noch) nicht berechnete Werte. Alle übersetzten Funktionen werden bei der Kompilierung in Thunks gelagert. Arbeitsweise: Thunks Thunks sind (noch) nicht berechnete Werte. Alle übersetzten Funktionen werden bei der Kompilierung in Thunks gelagert. Zur Laufzeit enthält ein Thunk entweder einen Funktionszeiger oder einen Wert. Arbeitsweise: Thunks... function Fay$$$(value){ this.forced = false; this.value = value; }... var Main$main = new Fay$$$(function(){...});... Arbeitsweise: Thunks... function Fay$$$(value){ this.forced = false; this.value = value; }... var Main$main = new Fay$$$(function(){...});... Arbeitsweise: Thunks... function Fay$$$(value){ this.forced = false; this.value = value; }... var Main$main = new Fay$$$(function(){...});... Arbeitsweise: Thunks Im Thunk gelagerter Wert wird über eine force Funktion evaluiert. Arbeitsweise: Thunks Im Thunk gelagerter Wert wird über eine force Funktion evaluiert. Thunk schon berechnet = return value Arbeitsweise: Thunks Im Thunk gelagerter Wert wird über eine force Funktion evaluiert. Thunk schon berechnet = return value Thunk noch nicht berechnet = return value() Arbeitsweise: Thunks Im Thunk gelagerter Wert wird über eine force Funktion evaluiert. Thunk schon berechnet = return value Thunk noch nicht berechnet = return value() Parameter ist kein Thunk = return Parameter Arbeitsweise: Thunks Im Thunk gelagerter Wert wird über eine force Funktion evaluiert. Thunk schon berechnet = return value Thunk noch nicht berechnet = return value() Parameter ist kein Thunk = return Parameter force = _ , bzw Fay$$_ Arbeitsweise: Funktionen Arbeitsweise: Funktionen Funktionen werden als Parameter für den Konstruktor eines Thunks übergeben. Arbeitsweise: Funktionen Funktionen werden als Parameter für den Konstruktor eines Thunks übergeben. Für jeden Parameter dieser Funktion wird ein Wrapper um den Konstruktor gelegt. Arbeitsweise: Funktionen f :: a = var Main$f = new Fay$$$(function(){...}) Arbeitsweise: Funktionen f :: a - a = var Main$f = function($p1){ return new Fay$$$(function(){...}) }; Arbeitsweise: Funktionen f :: a - a - a = var Main$f = function($p1){ return function($p2){ return new Fay$$$(function(){...}) }; }; Arbeitsweise: Funktionen Für jeden einzelnen Parameter ein Aufruf von force : Arbeitsweise: Funktionen Für jeden einzelnen Parameter ein Aufruf von force : f :: a - a Fay$$_(Main$f)(p1) Arbeitsweise: Funktionen Für jeden einzelnen Parameter ein Aufruf von force : f :: a - a Fay$$_(Main$f)(p1) f :: a - a - a Fay$$_(Fay$$_(Main$f)(p1))(p2) Arbeitsweise: Funktionen force liefert jeweils den Funktionszeiger zurück (keinen Thunk). Arbeitsweise: Funktionen force liefert jeweils den Funktionszeiger zurück (keinen Thunk). Das letzte force liefert einen Thunk zurück, in welchem die eigentliche Funktion gelagert ist. Arbeitsweise: Funktionen force liefert jeweils den Funktionszeiger zurück (keinen Thunk). Das letzte force liefert einen Thunk zurück, in welchem die eigentliche Funktion gelagert ist. Anwendung force auf den Thunk startet die Auswertung dieser Funktion. Arbeitsweise: Ein Beispiel Arbeitsweise: Ein Beispiel Simples Haskell-Programm: Arbeitsweise: Ein Beispiel Simples Haskell-Programm: module Demo(main) where f :: Int - Int f 0 = 0 f 1 = 1 f n = f (n-1) + f (n-2) main = putstrln (show (f 10)) Arbeitsweise: Ein Beispiel = f :: Int - Int f 0 = 0 f 1 = 1 f n = f (n-1) + f (n-2) Arbeitsweise: Ein Beispiel = f :: Int - Int f 0 = 0 f 1 = 1 f n = f (n-1) + f (n-2) var Demo$f = function($p1) { return new Fay$$$(function() {... }; }; Arbeitsweise: Ein Beispiel = f :: Int - Int f 0 = 0 f 1 = 1 f n = f (n-1) + f (n-2) var Demo$f = function($p1) { return new Fay$$$(function() {... }; }; Arbeitsweise: Patternmatching = f 0 = 0 if (Fay$$_($p1) === 0) { return 0; } Arbeitsweise: Patternmatching = f 1 = 1 if (Fay$$_($p1) === 1) { return 1; } Arbeitsweise: Ein Beispiel = f n = f (n-1) + f (n-2) Arbeitsweise: Ein Beispiel = f n = f (n-1) + f (n-2) return Fay$$_(Fay$$_(Fay$$add)(Fay$$_(Demo$f) (Fay$$_(Fay$$_(Fay$$sub)(n))(1))))(Fay$$_ (Demo$f)(Fay$$_(Fay$$_(Fay$$sub)(n))(2))); Arbeitsweise: Ein Beispiel = f n = f (n-1) + f (n-2) return Fay$$_(Fay$$_(Fay$$add) (Fay$$_(Demo$f) (Fay$$_(Fay$$_(Fay$$sub)(n))(1)))) (Fay$$_(Demo$f) (Fay$$_(Fay$$_(Fay$$sub)(n))(2))); Arbeitsweise: Ein Beispiel = f n = f (n-1) + f (n-2) return Fay$$_(Fay$$_(Fay$$add) (Fay$$_(Demo$f) (Fay$$_(Fay$$_(Fay$$sub)(n))(1)))) (Fay$$_(Demo$f) (Fay$$_(Fay$$_(Fay$$sub)(n))(2))); Arbeitsweise: Ein Beispiel = f n = f (n-1) + f (n-2) return Fay$$_(Fay$$_(Fay$$add) (Fay$$_(Demo$f)(n-1))) (Fay$$_(Demo$f)(n-2))); Arbeitsweise: Ein Beispiel = f n = f (n-1) + f (n-2) return Fay$$_(Fay$$_(Fay$$add) (f (n-1))) (f (n-2))); Arbeitsweise: Ein Beispiel = f n = f (n-1) + f (n-2) return (f (n-1)) + (f (n-2)); Arbeitsweise: Datentypen Arbeitsweise: Datentypen JavaScript hat dynamische Typisierung Arbeitsweise: Datentypen JavaScript hat dynamische Typisierung Keine Typüberprüfung zur Laufzeit Arbeitsweise: Datentypen JavaScript hat dynamische Typisierung Keine Typüberprüfung zur Laufzeit Korrekte Typverwendung bei Funktionen beim Kompilieren mit Fay geprüft Arbeitsweise: Datentypen JavaScript hat dynamische Typisierung Keine Typüberprüfung zur Laufzeit Korrekte Typverwendung bei Funktionen beim Kompilieren mit Fay geprüft f :: Int - String main = putstrln (f hallo Welt ) = Compilerfehler Summendatentypen Patternmatching mit Konstruktoren Summendatentypen Patternmatching mit Konstruktoren data Wert = Zahl Int Text String f :: Wert - String f (Zahl i) = Eine Zahl: ++ (show i) f (Text s) = Ein Text: ++ s Summendatentypen Fay übersetzt die Konstruktoren des Summendatentyps: Summendatentypen Fay übersetzt die Konstruktoren des Summendatentyps: var $_Main$Zahl = function(slot1){ this.slot1 = slot1; }; var $_Main$Text = function(slot1){ this.slot1 = slot1; }; Summendatentypen Patternmatching mit instanceof ... if (Fay$$_($p1) instanceof $_Main$Zahl) {...}... Arbeitsweise: Listen Arbeitsweise: Listen //Konstruktor für Liste function Fay$$Cons(car,cdr){ this.car = car; // Erstes Element this.cdr = cdr;// Restliste } Arbeitsweise: Listen //Konstruktor für Liste function Fay$$Cons(car,cdr){ this.car = car; // Erstes Element this.cdr = cdr;// Restliste } car: Contents of Adress part of Register number cdr: Contents of Decrement part of Register number Arbeitsweise: Listen //Konstruktor für Liste function Fay$$Cons(car,cdr){ this.car = car; // Erstes Element this.cdr = cdr;// Restliste } function Fay$$cons(x){ return function(y){ return new Fay$$Cons(x,y); }; } Arbeitsweise: Listen [1,2,3] = [1..10] = [1..] = Fay ist toll = Arbeitsweise: Listen [1,2,3] = Fay$$list([1,2,3]) [1..10] = Prelude$enumFromTo(1)(10) [1..] = Prelude$enumFrom(1) Fay ist toll = Fay$$list( Fay ist toll ) Arbeitsweise: Listen Fay$$list Arbeitsweise: Listen Fay$$list Arbeitet Eingabearray von hinten nach vorne ab Arbeitsweise: Listen Fay$$list Arbeitet Eingabearray von hinten nach vorne ab Rückgabe z.b.: Cons(1,Cons(2,Cons(3, null))) Arbeitsweise: Listen Fay$$list Arbeitet Eingabearray von hinten nach vorne ab Rückgabe z.b.: Cons(1,Cons(2,Cons(3, null))) Prelude$enumFrom Arbeitsweise: Listen Fay$$list Arbeitet Eingabearray von hinten nach vorne ab Rückgabe z.b.: Cons(1,Cons(2,Cons(3, null))) Prelude$enumFrom Parameter wird erstes Element der Liste Arbeitsweise: Listen Fay$$list Arbeitet Eingabearray von hinten nach vorne ab Rückgabe z.b.: Cons(1,Cons(2,Cons(3, null))) Prelude$enumFrom Parameter wird erstes Element der Liste Restliste ein Thunk Arbeitsweise: Listen Fay$$list Arbeitet Eingabearray von hinten nach vorne ab Rückgabe z.b.: Cons(1,Cons(2,Cons(3, null))) Prelude$enumFrom Parameter wird erstes Element der Liste Restliste ein Thunk Cons(i, Prelude$enumFrom(i+1)) Arbeitsweise: Listen Fay$$list Arbeitet Eingabearray von hinten nach vorne ab Rückgabe z.b.: Cons(1,Cons(2,Cons(3, null))) Prelude$enumFrom Parameter wird erstes Element der Liste Restliste ein Thunk Cons(i, Prelude$enumFrom(i+1)) Prelude$enumFromTo Arbeitsweise: Listen Fay$$list Arbeitet Eingabearray von hinten nach vorne ab Rückgabe z.b.: Cons(1,Cons(2,Cons(3, null))) Prelude$enumFrom Parameter wird erstes Element der Liste Restliste ein Thunk Cons(i, Prelude$enumFrom(i+1)) Prelude$enumFromTo Wie Prelude$enumFrom, aber mit Abbruchbedingung Arbeitsweise: Listen Beispiel für Lazy Evaluation Arbeitsweise: Listen Beispiel für Lazy Evaluation head [1..] Arbeitsweise: Listen Beispiel für Lazy Evaluation head [1..] = head Fay$$Cons(1, Thunk) Arbeitsweise: Listen Beispiel für Lazy Evaluation head [1..] = head Fay$$Cons(1, Thunk) = 1 Foreign Function Interface Foreign Function Interface Kein Zugriff auf Elemente einer HTML Seite. Foreign Function Interface Kein Zugriff auf Elemente einer HTML Seite. Fay bietet FFI um dem entgegenzukommen. Foreign Function Interface Kein Zugriff auf Elemente einer HTML Seite. Fay bietet FFI um dem entgegenzukommen. Stellt die Möglichkeit dar, um direkt JavaScriptcode in Haskell zu verwenden. Foreign Function Interface module Hello(main) where import FFI alert :: String - Fay() alert = ffi alert(%1) main = alert Hello World Foreign Function Interface ffi hat genau einen Parameter (String)! Foreign Function Interface ffi hat genau einen Parameter (String)! Punktfreie Notation notwendig! Foreign Function Interface Punktfreie Notation: plusone :: Int - Int plusone x = 1 + x Foreign Function Interface Punktfreie Notation: plusone :: Int - Int plusone x = 1 + x //gleichwertig mit plusone x = (+) 1 x Foreign Function Interface Punktfreie Notation: plusone :: Int - Int plusone x = 1 + x //gleichwertig mit plusone x = (+) 1 x //gleichwertig mit plusone = (+) 1 Foreign Function Interface Punktfreie Notation: plusone x = (+) 1 x = nicht Punktfrei plusone = (+) 1 = Punktfrei Foreign Function Interface ffi hat genau einen Parameter (String)! Punktfreie Notation notwendig! %1 , %2 , %3 , etc. innerhalb des Strings werden ersetzt durch die Parameter der Funktion. Foreign Function Interface Der Parameter von ffi wird als JavaScriptcode interpretiert. Foreign Function Interface Der Parameter von ffi wird als JavaScriptcode interpretiert. Keinerlei Compilerprüfung dieses Codes. Foreign Function Interface Der Parameter von ffi wird als JavaScriptcode interpretiert. Keinerlei Compilerprüfung dieses Codes. = Fehleranfällig Foreign Function Interface ffi ist nur eine Pseudofunktion. Foreign Function Interface ffi ist nur eine Pseudofunktion. Fay setzt den Stringparameter als JavaScriptcode in die kompilierte Funktion ein. Foreign Function Interface ffi ist nur eine Pseudofunktion. Fay setzt den Stringparameter als JavaScriptcode in die kompilierte Funktion ein. = Der Haskellcode lässt sich mit ffi nicht mehr im GHC kompilieren!!! Foreign Function Interface ffi :: String - a ffi = error Language.Fay.FFI.foreignFay: Used foreign function not in a JS engine context. Foreign Function Interface ffi :: String - a ffi = error Language.Fay.FFI.foreignFay: Used foreign function not in a JS engine context. Foreign Function Interface ffi :: String - a ffi = error Language.Fay.FFI.foreignFay: Used foreign function not in a JS engine context. Typsignatur der aufrufenden Funktion bestimmt Konversionsverhalten im generierten Code. Foreign Function Interface round :: Double - Int round = ffi Math.round(%1) Foreign Function Interface round :: Double - Int round = ffi Math.round(%1) = return Fay$$jsToFay_int (Math.round(Fay$$fayToJs_double($p1))); Foreign Function Interface round :: Double - Int round = ffi Math.round(%1) = return Fay$$jsToFay_int (Math.round(Fay$$fayToJs_double($p1))); Foreign Function Interface alert :: String - Fay() alert = ffi alert(%1) Foreign Function Interface = alert :: String - Fay() alert = ffi alert(%1) var Fib$alert = function($p1){ return new Fay$$$(function(){ return new Fay$$Monad (Fay$$jsToFay([ unknown ], alert(fay$$faytojs_string($p1)))); }); }; Foreign Function Interface = alert :: String - Fay() alert = ffi alert(%1) var Fib$alert = function($p1){ return new Fay$$$(function(){ return new Fay$$Monad (Fay$$jsToFay([ unknown ], alert(fay$$faytojs_string($p1)))); }); }; Foreign Function Interface Wird die Fay-Monade erstellt, wird alert ausgeführt. Foreign Function Interface Wird die Fay-Monade erstellt, wird alert ausgeführt. Der Rückgabewert von alert wird in der Fay- Monade gespeichert. Foreign Function Interface Wird die Fay-Monade erstellt, wird alert ausgeführt. Der Rückgabewert von alert wird in der Fay- Monade gespeichert. Fay-Monade zum Ignorieren des Rückgabewertes eines ffi-aufrufs. FFI Beispiele FFI Beispiele Online Fibonacci-Rechner Live FFI Beispiele Eingabedatenprüfer Live Einschränkungen Was kann Fay nicht? Einschränkungen Kein Support für Typklassen Einschränkungen Kein Support für Typklassen Funktionen wie read nicht implementiert Einschränkungen Kein Support für Typklassen Funktionen wie read nicht implementiert ffi parseint(%1) kann dies jedoch ersetzen Einschränkungen Kein Support für Typklassen Funktionen wie read nicht implementiert ffi parseint(%1) kann dies jedoch ersetzen Import unterstützt nicht übliche Haskellbibliotheken Einschränkungen Kein Support für Typklassen Funktionen wie read nicht implementiert ffi parseint(%1) kann dies jedoch ersetzen Import unterstützt nicht übliche Haskellbibliotheken Prelude und FFI Einschränkungen Kein Support für Typklassen Funktionen wie read nicht implementiert ffi parseint(%1) kann dies jedoch ersetzen Import unterstützt nicht übliche Haskellbibliotheken Prelude und FFI z.b. kein Control.Monad, Data.Map, etc Einschränkungen Numbercrunching nur bedingt möglich Einschränkungen Numbercrunching nur bedingt möglich JavaScript speichert alle Zahlen als Doubles Einschränkungen Numbercrunching nur bedingt möglich JavaScript speichert alle Zahlen als Doubles Größere Zahlen als bei Int in Haskell möglich Einschränkungen Numbercrunching nur bedingt möglich JavaScript speichert alle Zahlen als Doubles Größere Zahlen als bei Int in Haskell möglich Nur etwa die ersten 15 Stellen genau Einschränkungen Numbercrunching nur bedingt möglich JavaScript speichert alle Zahlen als Doubles Größere Zahlen als bei Int in Haskell möglich Nur etwa die ersten 15 Stellen genau Sobald FFI importiert ist, kann der Haskellcode nicht mehr im GHC kompiliert werden Einschränkungen Numbercrunching nur bedingt möglich JavaScript speichert alle Zahlen als Doubles Größere Zahlen als bei Int in Haskell möglic
Similar documents
View more...
We Need Your Support
Thank you for visiting our website and your interest in our free products and services. We are nonprofit website to share and download documents. To the running of this website, we need your help to support us.

Thanks to everyone for your continued support.

No, Thanks