1 Punkte von GN⁺ 2024-12-04 | Noch keine Kommentare. | Auf WhatsApp teilen
  • Ein Entwickler vergleicht auf Basis seiner Erfahrungen mit 8 Jahren Haskell und 8 Monaten OCaml in der Produktion das tatsächliche Entwicklungsgefühl der beiden funktionalen Sprachen
  • Haskell bietet eine knappere Syntax und starke Typfunktionen, lenkt aber durch die große Zahl an Möglichkeiten leicht die Aufmerksamkeit auf Design und Abstraktion
  • OCaml wird trotz weniger Features als Sprache bewertet, mit der man sich dank First-Class-Modules, praktischer Mutabilität und eines vorhersehbaren Code-Stils leichter auf die Implementierung konzentrieren kann
  • Das Ökosystem von Haskell ist größer, aber die Auswahl von Bibliotheken kann sich wie eine eigene Disziplin anfühlen, während in OCaml trotz kleinerem Umfang die nötigen Werkzeuge überraschend gut funktionieren
  • Beide Sprachen sind kleiner als Mainstream-Sprachen und ihre Standardbibliotheken sind eher minimal, können aber für industrielle Anwendungen völlig ausreichen, solange man nicht stark von bestimmten SDKs abhängt

Ausgangspunkt des Vergleichs

  • Die Grundlage sind 8 Jahre Nutzung von Haskell und 8 Monate Nutzung von OCaml in der Produktion
  • Verglichen werden Syntax, Sprachfeatures, Ökosystem, Tools, Compiler-Meldungen und Standardbibliothek
  • Beide Sprachen haben sich genug weiterentwickelt, um reale industrielle Anforderungen zu unterstützen, aber die aktuelle Präferenz geht eher in Richtung OCaml

Syntax: Haskell ist kompakter, aber auch OCaml hat die Vorteile der ML-Familie

  • Mit Haskell lassen sich Ideen mit sehr wenigen Zeichen ausdrücken, was ein starkes Gefühl syntaktischer Eleganz vermittelt
  • Auch OCaml ist als Sprache der ML-Familie hervorragend, aber Haskell bietet einen stärker impliziten (tacit) Stil
  • Im Beispiel zum Aufsummieren von Zahlen in einem String drückt Haskell dies kurz als sum . map read . words aus, während OCaml per Pipeline das Aufteilen, Umwandeln und Falten des Strings explizit beschreibt
  • Die Definition eines Binärbaum-Typs drückt in beiden Sprachen algebraische Datentypen natürlich aus
  • Beim Parsing-Beispiel nutzen beide Sprachen Pattern Matching und Option-Werte, aber Haskell verwendet do-Notation und guard, OCaml dagegen Option.bind und explizites match

Features: Haskell ist reichhaltiger, OCaml weniger zerstreuend

  • Haskell hat sehr viele Features, so viele, dass sich als Vergleich eher C++ aufdrängt
  • Diese vielen Features sind Werkzeuge, um Probleme sehr präzise zu lösen, können aber schon vor der eigentlichen Implementierung dazu führen, dass man über den Lösungsansatz selbst grübelt
  • In Haskell verliert man sich leicht in Designentscheidungen rund um Optionen wie TypeFamilies, DataKinds und GADTs
  • Ein schlechter Zustand in bestehenden OCaml-Projekten bedeutet meist fehlende Variablennamen, fehlende Dokumentation oder Funktionen mit mehr als 200 Zeilen und gilt damit noch als beherrschbar
  • Dagegen kann man in bestehenden Haskell-Projekten auf Komplexität stoßen, auf die selbst 8 Jahre Erfahrung nicht vorbereiten
  • Durch diesen Unterschied fühlt sich die Arbeit in OCaml produktiver an
  • Von beiden Sprachen geteilte Features

    • Beide bieten eine ausdruckszentrierte Syntax, standardmäßige Immutabilität, Higher-Order Functions, anonyme Funktionen, algebraische Datentypen und Pattern Matching
    • Parametrische Polymorphie, Type Inference, syntaktischen Zucker für Monaden, Garbage Collector, Multithreading und GADTs kann man ebenfalls in beiden nutzen
  • In Haskell stärker ausgeprägte Features

    • Haskell bietet standardmäßige Reinheit, komponierbare Lazy Evaluation, Type Classes, Higher-Kinded Types und optionale Sprach-Erweiterungen
    • Weil es so viele mächtige Features gibt, kann sich die Art der Abstraktion von Projekt zu Projekt stark unterscheiden
  • In OCaml stärker ausgeprägte Features

    • OCaml bietet First-Class-Modules, polymorphe Varianten, Objekte, Klassen und Vererbung sowie leicht nutzbare Mutabilität
    • Die Bandbreite der Features ist kleiner als bei Haskell, was den Vorteil hat, dass sich Codebasen leichter vorhersagen lassen

Ökosystem: Haskell ist größer, OCaml hat die nötigen Lösungen

  • Beide Sprachen sind Nischen-Sprachen der funktionalen Programmierung, daher ist erstklassige Unterstützung für die neuesten Frameworks schwer zu erwarten
  • Trotzdem gibt es für die meisten allgemeinen Aufgaben Lösungen, auch wenn man in manchen Fällen zusätzliche Custom Bindings schreiben muss
  • Auch in OCaml findet man Pakete für die Praxis wie etwa:
  • Das Haskell-Ökosystem bietet mehr Pakete und mehr sofort einsetzbare Lösungen
  • Für die Stripe API gibt es in Haskell 13 Client-Bibliotheken, in OCaml nur 1, und diese OCaml-Bibliothek wurde zuletzt vor 8 Jahren geändert, also faktisch eher 0
  • In Haskell muss man nach dem Finden einer Lösung zusätzlich noch beurteilen, welche Bibliothek man unter zu vielen Optionen wählen soll
  • Die Auswahl von Bibliotheken wird teils wie eine eigene Fähigkeit behandelt, sodass es sogar Texte zur Bewertung von Bibliotheken gibt
  • Neue Haskell-Bibliotheken entstehen oft nicht, um ein anderes Problem zu lösen, sondern weil jemand es mit einer anderen Abstraktion oder einem neuen Feature anders schreiben wollte
  • Es kann interessanter sein, einen Logger mit Comonads zu entwerfen, als einen GitHub-API-Client zu bauen und viel JSON zu parsen

Tools: Haskell ist mächtig, aber schwankend, OCaml funktioniert einfach

  • Haskell-Tools vereinen starke Vorteile mit Problemen bei der Nutzbarkeit
  • Hoogle ist ein mächtiges Werkzeug, mit dem sich das gesamte Ökosystem allein über Typ-Signaturen durchsuchen lässt
  • Gleichzeitig gibt es Probleme wie Fehlermeldungen von Build-Tools, Situationen, in denen bei einem funktionierenden Projekt kein Build-Plan gefunden wird, Re-Kompilierung der IDE nach Paketänderungen oder fehlende Dokumentation der Standardbibliothek für bestimmte Versionen
  • Die Erfahrung mit Haskell-Tools schwankt zwischen Momenten, in denen man sich fragt, wie andere Sprachen ohne solche Werkzeuge überhaupt verwendet werden, und Momenten, in denen man sich fragt, wie Haskell-Nutzer mit der fehlenden grundlegenden Nutzbarkeit leben
  • Bei OCaml überrascht eher, wie oft man trotz kleinerem Ökosystem Dinge findet, die einfach funktionieren
  • Das LSP-basierte VSCode-OCaml-Plugin funktionierte ohne besondere Anpassungen und ohne Probleme
  • Der Einstieg in die OCaml-Tooling-Welt ist vielleicht nicht maximal bequem, aber intuitiv, robust und funktioniert in den meisten Fällen zuverlässig
  • Tool-Vergleich

Compiler-Meldungen: Haskell ist wortreich, OCaml knapp

  • In funktionalen Sprachen ist der Compiler ein zentrales Werkzeug, um zu verstehen, warum der Code die beabsichtigten Annahmen nicht erfüllt
  • Deshalb sollten Fehlermeldungen die nötigen Informationen leicht zugänglich darstellen
  • Compiler-Meldungen in Haskell enthalten viel Kontext und sind ausführlich, neigen aber auch zu redundanten oder zerstreuenden Informationen
  • Compiler-Meldungen in OCaml sind recht knapp und manchmal sogar zu knapp
  • Das Beispielprogramm mit Fehler versucht in Haskell per x = 1 + [3, 1, 2] und in OCaml per let x = 1 + [3; 1; 2] eine Ganzzahl mit einer Liste zu addieren

Standardbibliothek: Beide sind minimal, aber Haskell glänzt bei der Dokumentation

  • Die Standardbibliothek prägt sowohl die ersten Programme in einer Sprache als auch die spätere Nutzungserfahrung
  • Eine gute Standardbibliothek ist die Grundlage für den Erfolg einer Programmiersprache, während eine schwache Standardbibliothek endlose Debatten über alternative Standardbibliotheken auslösen kann
  • Eine wünschenswerte Standardbibliothek sollte eher dem batteries-included-Ansatz folgen
  • Zur gewünschten Ausstattung zählen ein Option-ähnlicher Typ, UTF-8-Strings, Map und HashMap, JSON- und XML-Parser sowie asynchrone Primitive
  • Wer nicht erst den Bau von Build-Tools und Dependency-Tracking lernen will, braucht mehr Funktionalität in der Standardbibliothek
  • Build Systems a la Carte analysiert den Bereich von Dependency Trackern und Build-Tools
  • Sowohl Haskell als auch OCaml haben eine vergleichsweise minimale Standardbibliothek
    • In Haskell fehlen Map und HashMap in der Standardbibliothek
    • In OCaml fehlen non-empty lists und Bitraversable
  • Die Haskell-Standardbibliothek ist base, OCaml verwendet die OCaml standard library
  • Die Qualität der Haskell-Dokumentation ist teilweise so gut, dass selbst erfahrene Entwickler überrascht sind
  • Zu den Stärken der Haskell-Dokumentation gehört auch die Möglichkeit, direkt zum Quellcode zu springen; für OCaml sei eine ähnliche Funktion wohl in Vorbereitung
  • Dokumentationsbeispiele

    • Beispiele aus der Haskell-List-Dokumentation
    • Beispiele aus der OCaml-List-Dokumentation
    • Selbst bei Funktionen mit offensichtlichem Ergebnis vermitteln beispielzentrierte Dokumentationen sofort ein Gefühl dafür, wie sich eine API einsetzen lässt

Fazit: Beide taugen für den industriellen Einsatz, aber derzeit mit Präferenz für OCaml

  • Beide Sprachen haben sich stark genug entwickelt, um reale industrielle Anforderungen zu unterstützen
  • Im Vergleich zu Mainstream-Sprachen bleiben es dennoch eher kleine Sprachen
  • Solange man nicht kritisch von der Existenz bestimmter SDKs abhängt, kann man mit beiden Sprachen die nächste Anwendung mit Freude entwickeln
  • Derzeit wird OCaml als Sprache bewertet, mit der man sich leichter auf das tatsächliche Bauen von Dingen konzentrieren kann

Noch keine Kommentare.

Noch keine Kommentare.