Erstgespräch vereinbaren
Kommende Termine
4. Mai 2026
IT-Talk: Digitale Verantwortung
Details →
12. Juni 2026
Vernissage
28. September 2026
IT-Talk: Event-Driven Architecture

Elm - funktionale Programmierung im Browser

Einführung in Elm: Funktionale Programmierung für den Browser mit starkem Typsystem, ohne Runtime-Exceptions.

Farbiger Programmcode auf einem Bildschirm

Was hat funktionale Programmierung im Browser zu suchen? Diese Frage stellte sich der Autor, bevor er auf Evan Czaplickins Vortrag “Let’s Be Mainstream” auf der Curry-On 2015 stieß, der zum Ziel hatte, “eine Programmiersprache mit sowohl sehr guter Benutzbarkeit als auch sehr guter Wartbarkeit” zu schaffen.

Was ist Elm?

Elm ist eine junge Sprache (entstanden 2012), die zu JavaScript kompiliert und im Browser läuft. Die wichtigsten Eigenschaften:

  • Typisierung: Statisch typisiert mit Typinferenz; Typannotationen sind optional, aber empfohlen
  • Unveränderlichkeit: Alle Daten sind unveränderlich (immutable)
  • Reinheit: Keine Seiteneffekte erlaubt; der Compiler erzwingt reine Funktionen
  • Syntax: Abgeleitet von ML-Sprachen (Haskell, OCaml, F#), mit minimalen Klammern und Kommata
  • Fehlerbehandlung: Kein null, undefined oder try…catch; praktisch keine Runtime-Exceptions

Die Sprache betont “praktische Benutzbarkeit über akademische Komplexität” und vermeidet bewusst mathematischen Jargon in der Dokumentation.

Hello World

import Html exposing (text)

main =
  text "Hello, World!"

Programme kompilieren zu einer eigenständigen HTML-Datei (~180KB) via elm make <dateiname>.

Die Elm-Architektur

Ein Zähler-Beispiel demonstriert die Kernkonzepte:

import Html exposing (beginnerProgram, div, button, text)
import Html.Events exposing (onClick)

main =
  beginnerProgram { model = 0, view = view, update = update }

view model =
  div []
    [ button [ onClick Decrement ] [ text "-" ]
    , div [] [ text (toString model) ]
    , button [ onClick Increment ] [ text "+" ]
    ]

type Msg = Increment | Decrement

update msg model =
  case msg of
    Increment ->
      model + 1
    Decrement ->
      model - 1

Die Architektur besteht aus drei Komponenten:

  1. Model: Der Programmzustand (initial ein einzelner Integer)
  2. View: Rendert HTML basierend auf dem aktuellen Model
  3. Update: Verarbeitet Nachrichten und erzeugt einen neuen Model-Zustand

Zur Laufzeit rendert die Elm-Runtime die View, lauscht auf Benutzerinteraktionen die Nachrichten erzeugen, ruft Update mit der Nachricht und dem aktuellen Model auf, empfängt ein neues Model und rendert erneut. Ein virtuelles DOM stellt sicher, dass nur Änderungen auf das tatsächliche DOM angewendet werden.

Sprachfeatures

Union Types: Elm ermöglicht prägnante Typdefinitionen:

type Demo = Alpha | Beta

Typsystem: Statische, inferierte, strukturelle Typisierung. Unterstützt partielle Anwendung und Currying auf natürliche Weise.

Kein Null/Exceptions: Eliminiert ganze Klassen von Laufzeitfehlern.

Entwicklungserfahrung

Das praktische Experiment des Autors bestand darin, das Spring PetClinic Frontend in Elm neu zu implementieren.

Compiler-Feedback

Fehlermeldungen sind bemerkenswert hilfreich und bieten Vorschläge:

Cannot find type Location
Maybe you want one of the following?
Navigation.Location

Modularisierung

Code existierte zunächst in einer einzigen Datei. Beim Hinzufügen datenabhängiger Views refaktorisierte der Autor in separate Module nach elm-tutorial.org-Patterns.

HTTP-Requests

Elm verhindert direkte Seiteneffekte. Stattdessen geben Update-Funktionen Commands zurück, die Aktionen für die Elm-Runtime beschreiben. Der Autor stieß auf CORS-Probleme, als er die HTML-Datei direkt öffnete anstatt sie über die Spring-Anwendung auszuliefern – kein Elm-spezifisches Problem, sondern eine JavaScript-Sicherheitsmaßnahme.

Das Hinzufügen von Browser-History und korrektem URL-Handling erforderte die Einführung des Navigation-Moduls. Der Autor fand relevante Tutorials, stellte aber fest, dass einige veraltet waren (Elm 0.17 vs. Arbeitsversion 0.18), was kleinere Anpassungen erforderte.

IDE-Unterstützung

IntelliJ IDEA mit Elm-Plugin bietet Syntax-Highlighting, Auto-Vervollständigung, Refactoring-Unterstützung und Symbol-Navigation.

Beobachtete Stärken

  1. Erlernbarkeit: Kleine Sprachoberfläche; gute Dokumentation und Beispiele
  2. Refactoring-Sicherheit: Der Compiler verhindert das Vergessen notwendiger Änderungen; fast alles funktioniert sofort nach der Kompilierung
  3. Modulsystem: Verhindert zirkuläre Abhängigkeiten und erfordert explizite transitive Abhängigkeitsdeklaration
  4. Type-Driven Development: Leichtgewichtige Typerstellung fördert Domain-Typen (UserId) statt Primitiven und verbessert die Code-Klarheit
  5. Debugging: Der Time-Travelling Debugger zeichnet alle Interaktionen und Zustandsänderungen seit App-Start auf und ermöglicht retrospektive Zustandsinspektion
  6. Testing: Reine Funktionen erfordern keine Mocks; deterministisches Verhalten vereinfacht das Testen
  7. Fehlervermeidung: Union Types und strikte Typisierung machen “unmögliche Zustände unmöglich”

Herausforderungen und Einschränkungen

  • Schnelle Weiterentwicklung: Elm verändert sich schnell; Versions-Upgrades sind für langlebige Projekte notwendig
  • Community-Abhängigkeit: Das Community-Wachstum ist stark, aber stark abhängig vom Schöpfer Evan Czaplicki
  • Migrationsschwierigkeit: Die schrittweise Migration bestehender SPAs zu Elm ist herausfordernd
  • DOM-Integration: Die Integration von JavaScript-Komponenten, die das DOM direkt manipulieren, kollidiert mit Elms virtuellem DOM-Ansatz; Web Components bieten mögliche Lösungen
  • Debugger-Probleme: Der neue Debugger hat Darstellungsprobleme
  • Tool-Reife: Die Tools sind nicht durchgehend ausreichend; der Compiler kann sich bei bestimmten Typinferenz-Szenarien verwirren

Fazit

Die Elm-Architektur – mit strikter Trennung von Model, View und Update-Funktionen – bietet exzellente Struktur und Skalierbarkeit. Die Elm-Architektur ist “näher am historischen Vorfahren Smalltalk-MVC als vieles, was heute ‘MVC’ im Namen trägt.”

Die strengen Prüfungen des Compilers, kombiniert mit der Effizienz des virtuellen DOM und dem Time-Travelling Debugger, schaffen eine Umgebung, in der “fast alles, was ich schrieb, sofort nach Bestehen des Compilers funktionierte.”

Trotz der Einschränkungen kann “der Einsatz von Elm in einem kleineren, nicht-kritischen Projekt schon jetzt sehr lohnenswert sein.” Die Umgebung ermöglicht schnelle Erfolge bei gleichzeitiger Beibehaltung von Code-Klarheit und Langlebigkeit.

Empfohlene Ressourcen

  • Offizielle Elm-Seite
  • awesome-elm (kuratierte Liste)
  • Elm Tutorial
  • Artikel von Dennis Reimann
  • codecentric: Elm Friday Serie
  • LinkedIn-Artikel zu Single-Page Web Apps in Elm
  • ElmSeeds Video-Serie
  • “How I Structure Elm Apps” Blog-Post
Zurück zum Blog