Edward Kmett hat THC („Turbo Haskell“) entwickelt, einen JIT- und AOT-Compiler für GHC 9.14.1 Core auf Basis von GraalVM und Truffle, der Haskell-Programme direkt auf der JVM ausführt. Das System übernimmt die Ausführung nach GHCs Parsing- und Optimierungsphasen und unterstützt fortgeschrittene Funktionen wie Template Haskell, Linear Haskell sowie ein polyglotes FFI zu Python, Ruby, R und JavaScript. THC nutzt Project Loom für leichtgewichtige Green Threads und implementiert eine neuartige Endrekursions-Optimierung (Tail Calls) mittels eines 64-Bit-Bloom-Filters und einer Stack-Kompaktierung.
Wichtigste Punkte
GraalVM- und Truffle-Architektur: THC setzt nach GHCs Optimierungsphase an, implementiert alle GHC 9.14.1 Prim-Ops und führt Haskell über einen Bytecode- sowie AST-basierten JIT-Compiler auf der JVM aus.
Polyglot-FFI und Interoperabilität: Bietet ein Nulllöschungs-FFI (Zero-Copy) für UTF-8-Strings zu Python, Ruby, R und JavaScript sowie C/C++ über Sulong (LLVM auf der JVM).
Fortschrittliche Sprachfeatures: Vollständige Unterstützung für Template Haskell, Linear Haskell, Cabal-Paketverwaltung (inklusive Backpack) und AOT-Kompilierung mittels GraalVM Native Image.
Concurrency und Green Threads: Nutzt Project Loom für leichtgewichtige, GHC-kompatible Green Threads mit einem HEC-basierten Runtime-Executor, MVars und asynchronen Ausnahmen (throwTo).
SIMD und Vektoroptimierung: Kombiniert GHC-Prim-Ops mit der inkubierenden Vector API (jdk.incubator.vector, JEP 508) zur Laufzeitauswahl von SIMD-Breiten.
Tail-Call-Optimierung: Verwendet einen 64-Bit-Bloom-Filter zur Erkennung rekursiver Endaufrufe, wandelt diese in enge Schleifen um und nutzt eine CHICKEN-Scheme-ähnliche Stack-Kompaktierung, um temporäre Stack-Überläufe zu bereinigen.
Performance-Metriken: Nutzt komprimierte Objektzeiger (Compressed Oops); die Leistung liegt nach der Aufwärmphase (Warmup) meist 10–20 % hinter GHC zurück (trotz zeitweiliger Regressionsphasen bei der Breitenerweiterung).
Diskussions-Highlights
Namensursprung und Anekdoten: Der Name „Turbo Haskell“ ist ein historischer Insiderwitz und spielt auf die häufige Fehlverhörung von Haskell als Pascal (analog zu Turbo Pascal) sowie auf eine blaue IDE an.
Historische Vergleiche: Diskutanten verwiesen auf Frege, einen älteren Haskell-Dialekt für die JVM, dessen Releases jedoch veraltet sind und dessen Entwicklung weitgehend stagniert.
FFI-Schnittstellen: Es wurde Verwunderung geäußert, warum Java in der initialen Liste der FFI-Sprachen des Artikels nicht explizit aufgeführt wurde, da das Ziel der Compiler die JVM ist.
Technische Skepsis: Einige Kommentatoren stellten die grundsätzliche Sinnhaftigkeit („Why?“) und den praktischen Nutzen der Kompilierung von Haskell auf die JVM infrage.
Infrastruktur-Probleme: Mehrere Nutzer berichteten, dass Antivirensoftware (wie Avast) den Zugriff auf die Quell-Website des Artikels fälschlicherweise blockiert.
Glossar
JIT-Compiler (Just-In-Time Compiler): Ein System, das Code zur Laufzeit direkt in maschinenlesbaren Maschinencode übersetzt, um die Ausführungsgeschwindigkeit zu steigern.
AOT-Kompilierung (Ahead-Of-Time): Die Übersetzung von Quellcode in binären Maschinencode vor der Programmausführung, wodurch kein JIT-Warmup zur Laufzeit erforderlich ist.
GHC Core: Eine vereinfachte, stark getypte Zwischenrepräsentation (Intermediate Representation) im Glasgow Haskell Compiler, auf deren Basis Optimierungen durchgeführt werden.
GraalVM & Truffle: Ein Hochleistungs-VM-Ökosystem von Oracle (GraalVM) und ein Framework (Truffle), mit dem sich Sprachen effizient als AST- oder Bytecode-Interpreten auf der JVM implementieren lassen.
Prim-Ops (Primitive Operations): Grundlegende, maschinennahe Operationen und Primitive, die direkt vom Compiler-Backend bereitgestellt werden.
Template Haskell: Ein Haskell-Erweiterungsmechanismus für Metaprogrammierung, mit dem Code zur Kompilierzeit generiert werden kann.
Linear Haskell: Ein Typsystem-Feature, das garantiert, dass bestimmte Werte exakt einmal verwendet werden (lineare Logik).
Backpack: Ein Modulsystem für Haskell, das parametrisierte Module und signaturbasierte Paketkomposition erlaubt.
FFI (Foreign Function Interface): Eine Schnittstelle, die es einer Programmiersprache ermöglicht, Code oder Bibliotheken aufzurufen, die in einer anderen Sprache geschrieben sind.
Sulong: Ein LLVM-Bitcode-Interpreter und -Compiler, der auf der GraalVM/JVM läuft und die Ausführung von C/C++ ermöglicht.
Project Loom: Ein Java-Projekt zur Einführung von leichtgewichtigen Threads (Virtual Threads) und strukturierter Nebenläufigkeit in die JVM.
HEC (Haskell Execution Context): Die virtuelle Ausführungsumgebung von GHC zur Steuerung von Green Threads und Prozessor-Kernen (Capabilities).
SIMD (Single Instruction, Multiple Data): Eine Rechenarchitektur, bei der ein einzelner Befehl parallel auf mehrere Datenpunkte angewendet wird (Vektorverarbeitung).
Bloom-Filter: Eine speichereffiziente, probabilistische Datenstruktur, die prüft, ob ein Element Teil einer Menge ist (mit der Möglichkeit von False Positives).
Compressed Oops (Ordinary Object Pointers): Eine JVM-Optimierung, bei der Heap-Referenzen als 32-Bit-Offsets anstelle von 64-Bit-Zeigern gespeichert werden, um den Speicherbedarf zu senken und den Cache zu schonen.