Fay Haskell auf Client-Seite

Werbung
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
f0=0
f1=1
f n = f (n-1) + f (n-2)
main = putStrLn (show (f 10))
Arbeitsweise: Ein Beispiel
f :: Int -> Int
f0=0
f1=1
f n = f (n-1) + f (n-2)
=>
Arbeitsweise: Ein Beispiel
f :: Int -> Int
f0=0
f1=1
f n = f (n-1) + f (n-2)
=>
var Demo$f = function($p1) {
return new Fay$$$(function() {
...
};
};
Arbeitsweise: Ein Beispiel
f :: Int -> Int
f0=0
f1=1
f n = f (n-1) + f (n-2)
=>
var Demo$f = function($p1) {
return new Fay$$$(function() {
...
};
};
Arbeitsweise: Patternmatching
f0=0
=>
if (Fay$$_($p1) === 0) {
return 0;
}
Arbeitsweise: Patternmatching
f1=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 FayMonade gespeichert.
Foreign Function Interface
Wird die Fay-Monade erstellt, wird "alert"
ausgeführt.
Der Rückgabewert von "alert" wird in der FayMonade 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öglich
○ Nur etwa die ersten 15 Stellen genau
● Sobald "FFI" importiert ist, kann der
Haskellcode nicht mehr im GHC kompiliert
werden
○ Schränkt die Testmöglichkeiten stark ein
Fazit
Ist Fay großartig?
Fazit
Ist Fay großartig?
Antwort: Jein!
Fazit
● Einfache Webapplikationen sind kompiliert
viel größer als gleichwertiges JS-Programm
Fazit
● Einfache Webapplikationen sind kompiliert
viel größer als gleichwertiges JS-Programm
● Mathematische Funktionen leicht in Haskell
programmierbar
Fazit
● Einfache Webapplikationen sind kompiliert
viel größer als gleichwertiges JS-Programm
● Mathematische Funktionen leicht in Haskell
programmierbar
● FFI ermöglicht nicht-funktionale
Programmierung
Fazit
● Einfache Webapplikationen sind kompiliert
viel größer als gleichwertiges JS-Programm
● Mathematische Funktionen leicht in Haskell
programmierbar
● FFI ermöglicht nicht-funktionale
Programmierung
● (Bisher) Fehlen von Haskellmodulen wie
Control, Data, etc.
Fazit
Fay ist ein interessanter Ansatz...
Fazit
Fay ist ein interessanter Ansatz...
...aber noch nicht produktiv einsetzbar.
Fazit
Fay ist ein interessanter Ansatz...
...aber noch nicht produktiv einsetzbar.
Die Betonung liegt auf "noch".
Fragen?
Ende
Herunterladen