favicon

Elm – Haskell im Browser

Von am 20.10.2015

Ich glaube, dass es eine Zeit im Leben eines jeden Programmierers gibt, in der er sich mit Haskell auseinander setzen muss. So ergeht es nun auch mir. An dieser Stelle würde ich euch gerne von meinen Erfahrungen mit dieser Sprache erzählen.

Die Chance, dass einem Webentwicklern Haskell unter kam, war und ist immer noch sehr gering. Es kompiliert zu Assembly und läuft daher schon mal nicht im Browser. Zusätzlich ist es als “akademische Sprache” verschrien, welche von der Industrie erfolgreich ignoriert wird. Es ist jedoch eine unbestreitbare Tatsache, dass funktionale Sprachen immer beliebter werden – und zurecht. Die jahrzehntelange Fehlentwicklung der Programmierung, die wir Objektorientierung nennen, scheint immer mehr Leuten endlich aufzufallen. Ohne Null aber mit parallelisierbaren (jep, das wird auch noch im Browser kommen) Algorithmen lebt es sich eben angenehmer.
Mit Elm ist Haskell nun auch endlich im Browser angekommen. Hier ein kleiner Ausschnitt eines Programmes:

---------------------------------------------------------
module ColorSliders where

import Color exposing (Color, toRgb)

type alias Model = List Color

type ModelAction
  = Set Color
  | Back


update : ModelAction -> Model -> Model
update action (x :: xs) =
  let all = x :: xs
  in
    case action of
      Set color -> if color == x then all else color :: all
      Back ->
        let
          newHistory' = List.drop 1 all
        in
          if List.isEmpty newHistory' then [Color.rgb 0 0 0] else newHistory'


view : Signal.Address ModelAction -> Model -> Html
view address (x::xs) =
  let
    rgb' color = (String.concat [(toString color.red)
                                ,","
                                ,(toString color.green)
                                ,","
                                ,(toString color.blue)])
    listItem color = li [] 
  in
    div []
      [view' address x
      ,view' address x
      ,input [type' "button"
             ,value "Back in Time"
             ,onClick address Back] []
      ,ol [] (List.map listItem (x :: xs))]

------------------------------------------------------------------------------

Man muss den Code nicht auf Anhieb verstehen, aber jeder Entwickler wird sofort die Toplevel-Definitionen wieder erkennen. Wir können ein Modul mit dem Namen ColorSliders erkennen, welches andere Module importiert. Zusätzlich definiert das Modul ein Model, Modelaktionen. Diese werden von einer “update”-Funktion verwendet, welche eine Modelaktion und ein Model erhält und dafür ein neues Model (ein neuer State) zurückliefert. Eine “view”-Funktion nimmt einen Callback für Aktionen und ein Model und gibt dafür HTML zurück. Keine großen Überraschungen hier. Jede Funktion kann mit einer Typdefinition versehen werden. Dies ist optional. Elm ist eine statisch-typisierte Sprache, d.h. alles hat einen eindeutigen Typ zur Kompilierzeit, der sich im Laufe des Programmes auch nicht ändern kann, jedoch ist der Compiler schlau genug, um Typen selbst herauszufinden, falls wir diese nicht angeben. Dies wird auch als “type inference” bezeichnet. Dies ist eine große Hilfe, da der Compiler sofort schreit, falls wir auf ein Attribut zugreifen wollen, dass es in der Definition des Typs nicht gibt. Auch Null gibt es nicht -> keine NullpointerExceptions.

Ich glaube es ist eine gute Übung, die gleiche Applikation in verschiedenen Sprachen umzusetzen. Dadurch erhält man auch einen guten Vergleich. Daher habe ich die App aus einen meiner vorherigen Beiträge (http://mfg.fhstp.ac.at/allgemein/funktionale-uis-mit-om/) in Elm realisiert.
Das Ergebnis ist natürlich das Gleiche. Der komplette Quellkode ist auch wieder dabei. Vergleicht die Lösungen. Ich hoffe ich konnte damit eure Neugier für andere Sprachen wecken. Haskell wird mich auf jeden Fall noch über Jahre hinweg beschäftigen.