Fay

Haskell auf Client-Seite

Alexander Mills (inf9433@fh-wedel.de)

Startseite | Inhaltsverzeichnis | Einleitung | Funktionsweise | Beispiele | Einschränkungen | Fazit | Quellen

Einschränkungen

Keine Typklassen

Ein wichtiges Feature von Haskell sind Typklassen. Mit ihnen lässt sich Überladung realisieren, also das Implementieren der selben Funktion für verschiedene Datentypen mit unterschiedlichem Verhalten. Ein Beispiel hierfür ist der der Gleichheitsoperator "==". Dieser ist für viele verschiedene Datentypen anwendbar, hat aber unterschiedliche Implementierungen. Die Gleichheit von Listen oder Strings ist anders zu berechnen als die Gleichheit von zwei Ganzzahlen.

Das Problem ist, dass Fay diese Typklassen zur Zeit nicht unterstützt. Der Grund dafür liegt darin, dass Typklassen über ein Wörterbuch implementiert sind, welches über das Typsystem Informationen bekommt.

Da solch ein Typinformationssystem jedoch in JavaScript fehlt, lassen sich Typklassen (bisher) nicht von Fay übersetzen.

  class Read a where
    read :: String -> a
  instance Read Int where
    read "42" = 42
  foo = read "42" * 2  
  

Umgesetzt wird aus diesem Code der Folgende:

  data Read a = Read
    { read :: String -> a }
  inst_Read_Int = Read
    { read = \ "42" -> 42 }
  foo = read inst_Read_Int "42" * 2
  

Das Problem ist, dass Fay ohne die Typinformationen, welche bei der Übersetzung nach JavaScript verloren gehen, die letzte Zeile nicht übersetzen kann. Ohne das Typsystem kann nicht eindeutig festgestellt werden, welcher Typ von "read" benutzt werden soll, da nicht klar ist welchen Rückgabewert "read" haben soll.


Die Funktion "read", welche normalerweise in Prelude definiert ist, fehlt in Fay. Um dennoch Strings zu anderen Typen zu wandeln können die Konvertierungsfunktionen von JavaScript mittels "ffi" genutzt werden (zum Beispiel "parseInt").

Das Fehlen von Typklassen bedeutet außerdem, dass es nicht möglich ist einfach eigene Monaden zu definieren, da dies normalerweise über Typklassen passiert.

Es ist dennoch das Ziel der Entwickler Typklassen in Fay zu implementieren. Eine Möglichkeit ist die GHC API, welche jedoch durch mangelnde Dokumentation erschwert wird. Eine andere Möglichkeit wäre es den vom GHC erzeugten Core-Code nach JavaScript zu übersetzen, anstelle des Haskellquellcodes. Jedoch wäre dieser Schritt zu sehr im "Low Level" Bereich und würde das Projekt ebenfalls stark in der Entwicklung verlangsamen. Somit werden Typklassen zur Zeit noch nicht unterstützt, auch wenn die Implementierung ein Ziel der Entwickler ist.


Importbeschränkung

Auch wenn "Prelude" und "FFI" mithilfe vom Schlüsselwort "import" in den Code mit eingebunden werden können, so ist das Ausmaß dieses Einbindens beschränkt. Nur die von Fay mitgelieferten Haskellmodule können hierfür verwendet werden. Dadurch fehlen wiederum wichtige Module wie "Control.Monad" und "Data.Map". Die Fehlende Funktionalität muss also vom Programmierer selbst implementiert werden, sofern dies mit den verfügbaren Methoden möglich ist. Durch das Entfallen von Typklassen können beispielsweise keine eigenen Monaden definiert werden.


Numbercrunching

Beim Berechnen von sehr großen Zahlen, welche über den Bereich von "Int" hinaus gehen, kann ein von Fay kompiliertes Programm noch weiterrechnen. Beispielsweise kann Haskell mit dem Datentyp Int nicht die 100. Fibonaccizahl berechnen, da hierbei die Grenze von einem 64-Bit Int überschritten wird. JavaScript hingegen kann Zahlen bis zirka 1,8 * 10 ^ 308 berechnen. Dies liegt daran, dass JavaScript alle Zahlen als Double repräsentiert. Der Nachteil ist jedoch der Verlust der Genauigkeit von großen Zahlen. Die 100. Fibonaccizahl ist nur "ungefähr" richtig berechnet, da die letzten Stellen mit dem Wert "0" dargestellt werden. Solange Fay nicht den Datentyp "Integer" aus Haskell, welcher theoretisch unendlich große Ganzzahlen erlaubt, in JavaScript implementiert, beispielsweise durch die Einbindung einer "Big Integer"-Bibliothek, ist Fay nicht für präzise arithmetische Berechnung von großen Zahlen geeignet.


Validierung mit GHC

Hat man ein Programm für Fay geschrieben, so lässt es sich theoretisch noch mithilfe des GHCs kompilieren und validieren. Dadurch lässt sich überprüfen, ob der erzeugte JavaScriptcode auch zu den selben Ergebnissen wie der Haskellcode kommt. Sobald jedoch das FFI-Modul eingebunden wird kann das Programm nur noch von Fay und nicht mehr vom GHC kompiliert werden. Dies liegt daran, dass das FFI-Modul für den GHC unbekannt ist, da es nur in den Fay-Quelldateiordnern vorliegt. Bindet man diese Quelldatei in Haskell ein, so lässt sich der Code zwar kompilieren, jedoch nicht vernünftig testen, da die "ffi"-Funktion außerhalb von Fay immer einen Fehler zurückgibt, wenn sie aufgerufen wird.

Sobald also das Foreign Function Interface in einem Haskellprogramm, welches mit Fay kompiliert werden soll, verwendet wird, muss das Debuggen innerhalb von JavaScript erfolgen. Eine Alternative wäre es, einzelne Funktionen des Programms als eigenständiges Programm im GHC zu kompilieren und so zu testen. Bei größeren Projekten ist dies jedoch nicht sonderlich praktikabel.