Integrated Haskell Platform: Rapid Prototyping mit Haskell und Nix

IHP ist ein Webframework jenseits des Mainstreams: Es setzt auf die funktionale Programmiersprache Haskell und den Paketmanager Nix.

In Pocket speichern vorlesen Druckansicht 3 Kommentare lesen

(Bild: Shutterstock)

Lesezeit: 14 Min.
Von
  • Bianca Lutz
Inhaltsverzeichnis

Was kommt dabei heraus, wenn man ein Web Development Framework à la Ruby on Rails mit Haskell und dem PaketmanagerNix aufbaut? Die Integrated Haskell Platform (IHP) von digitally induced liegt zwei Jahre nach dem ersten öffentlichen Release in Version 1.0 vor. Das Versprechen: schnelle und einfache Webentwicklung vom Prototyp bis in die Produktion, mit den Vorzügen, die Nix und Haskell zu bieten haben, aber ohne den Schmerz der steilen Lernkurve, für die beide bekannt sind.

Grund genug, die Probe aufs Exempel zu machen: Hält das Framework, was es verspricht? Wie einfach ist der Einstieg? Wieviel Nix und Haskell braucht es am Ende? Und vor allem: Wie gut gehen die typischen Webframework-Ideen nach MVC-Prinzip (Model/View Controller) und eine stark typisierte funktionale Sprache wie Haskell tatsächlich zusammen? Love Child oder Frankenstein? Yet Another Web Framework oder echter Mehrwert?

Ausprobieren ist der beste Weg, Antworten auf diese Fragen zu finden. Naturgemäß sind die gewonnenen Eindrücke subjektiv.

Der Blick auf IHP, die Fragen, die sich die Autorin stellt, was ihr auffällt und was nicht, sind von ihrer Biografie (siehe Artikelende) geprägt: Mit Ruby on Rails hat sie kaum gearbeitet, aber dafür begegnen ihr Haskell und Nix fast täglich.

Mit Nix und Haskell setzt IHP auf zwei erprobte, leistungsfähige Werkzeuge. Der Paketmanager Nix erlaubt es, wartbare, reproduzierbare und vor allem portable Entwicklungs- und Ausführungsumgebungen auf die Beine zu stellen. Haskells Typsystem und der unnachgiebige Compiler helfen, Programmierfehler frühzeitig zu entdecken.

Das funktionale Programmierparadigma, dem beide folgen, ist ein Wert an sich. Funktional entwickeln heißt, über das Was und nicht über das Wie zu sprechen. Praktisch führt das zu weniger Boilerplate und sprechendem, Refactoring-freundlichem Code.

Allerdings ist der Einstieg in die funktionale Programmierung nicht einfach. Die Denkweise ist ungewohnt: Zustand ist nicht allgegenwärtig und obskure mathematische Konzepte gehören zum Grundvokabular, das es zu meistern gilt.

Im Fall von Haskell kommt eine unüberschaubare Vielfalt an Paketen hinzu. Ein nur mäßiges Modulsystem tut sein Übriges. Wer frisch in die Programmiersprache einsteigt, sieht sich mit einer kaum handhabbaren Toolchain allein gelassen. Viele geben frustriert auf.

Hier will IHP Abhilfe schaffen: "Haskell for Non-Haskellers" lautet die Devise. Haskell-Infrastruktur, eine sinnvolle Paketauswahl, benötigte JavaScript-Pakete und ein PostgreSQL-Server: Die Entwicklungsumgebung bietet ein Komplettpaket, das sich dank Nix mehr oder weniger auf Knopfdruck einrichten lässt. Mehr als Nix, ein Editor und ein Browser sind für die Entwicklung nicht erforderlich. Batteries included? Check.

Um IHP verwenden zu können, muss Nix installiert sein. Anleitungen für Windows, Linux und Mac sind auf der Projektseite zu finden. IHP selbst ist als Nix-Paket verfügbar und mit nur einem Befehl systemweit installiert. Auch ein neues Projekt ist im Handumdrehen erstellt:

ihp-new myproject

Beim ersten Projekt ist etwas Geduld gefragt: Zehn bis fünfzehn Minuten kann es dauern, bis alle Projektabhängigkeiten installiert sind. Danach greift der Binary-Cache von Nix: Weitere Projekte sind schnell aufgesetzt, weil sie die Abhängigkeiten aus dem Cache übernehmen und keine erneute Kompilierung erforderlich ist.

Bevor es an die App-Entwicklung geht, gilt es den Editor zu konfigurieren, damit Funktionen wie Autovervollständigung und Syntaxhervorhebung funktionieren. In der Dokumentation findet sich eine Anleitung für einige gängige Editoren.

IHP hat einen Development-Server im Gepäck. Der Projektordner enthält ein Skript, um ihn mit der App gemeinsam zu starten:

cd myproject
./start

Der Server ist – vielleicht etwas großspurig – mit Integrated Development Environment betitelt. Schaltzentrale trifft es eher: Mit dem Schema Designer lässt sich das Datenbankschema anpassen: Eine Migrationsansicht dient dazu, Änderungen am Schema auf die Datenbank zu bringen, und eine Datenansicht zeigt die aktuell definierten Tabellen mit ihren jeweiligen Inhalten. Dort lassen sich die Tabelleninhalte direkt manipulieren und SQL-Queries absetzen.

Abgesehen von den Datenbanktools ist der Entwicklungsserver vor allem eine Button-Sammlung. Hier lassen sich unterschiedliche Codegeneratoren anstoßen, daneben gibt es Links zur App und zur IHP-Dokumentation und eine Log-Ansicht.

Aus funktionaler Sicht ungewohnt, aber für Web-Frameworks üblich, steht die Datenbanktabelle im Zentrum. Sie definiert das Domänenmodell und bildet den Ausgangspunkt der Entwicklung. Der erste Schritt besteht somit im Anlegen einer Tabelle. Das geht komfortabel über den Schema-Designer.

Mit dem Schema Designer lassen sich Datenbankartefakte auch ohne PostgreSQL-Kenntnisse anlegen und anpassen (Abb. 1).

Auch wer fließend Postgres spricht, wird die Bequemlichkeit zu schätzen wissen. Unauffällige, aber sinnvolle Standardvorgaben erleichtern die Arbeit: Tabellen erhalten anfangs eine UUID-Spalte, und einige gängige Metadaten-Spalten sind als Vorlagen verfügbar. Das Tool berücksichtigt den Spaltennamen bei der Typisierung, um beispielsweise für date_of_sth den passenden Typ Date vorzubelegen. Darüber hinaus führen gebräuchliche Typen die Auswahlliste an. Tabellen lassen sich mit wenigen Klicks definieren und erweitern.

Im Hintergrund entsteht ein reguläres DDL-Skript (Data Definition Language): Application/Schema.sql. Wer Funktionen in der GUI vermisst, kann das Skript im Editor bearbeiten. Der Entwicklungsserver reflektiert externe Änderungen. Die Arbeiten im Editor und der GUI können sich bei Bedarf abwechseln und gegenseitig ergänzen.

Das Framework überträgt Änderungen am Datenbankschema in Form von Migrationen auf den lokalen PostgreSQL-Server und migriert die Daten automatisch. Achtung: Nicht immer gelingt der automatische Datenumzug. Eine Pflichtspalte (NOT NULL) ohne Default lässt sich nur in mehreren Schritten hinzufügen:

  1. Neue Spalte noch ohne NOT NULL-Constraint hinzufügen und Datenbank migrieren.
  2. Daten exportieren: make dumpdb.
  3. Den Dump in Application/Fixtures.sql nach Herzenslust bearbeiten.
  4. Daten wieder einspielen: make db.
  5. NOT NULL-Constraint an die neue Spalte hängen und die Datenbank erneut migrieren.

Weitere Details rund um das Thema Migrationen finden sich im IHP-Guide.