// HEISE ONLINE — MOBILE & WEB
Im Test: Elixirs 1.20 neues intelligentes Typsystem
Das Typsystem von Elixir 1.20 analysiert jedes Sprachkonstrukt, erkennt fehlerhafte Argumente und verfolgt sie auch.
Eine Funktion erwartet eine Zahl, aber irgendwo im Projekt wird stattdessen eine Zeichenkette übergeben. Der Compiler sagt nichts, die Tests decken den Fall nicht ab, und der Fehler tritt erst auf, wenn ein Kunde in der Produktion genau diesen Codepfad auslöst. Wer mit dynamisch getypten Sprachen arbeitet, kennt diese Klasse von Bugs: Typen werden erst zur Laufzeit geprüft, der Compiler trifft über sie von sich aus keine Annahmen.
Python, Ruby und JavaScript funktionieren nach diesem Prinzip, die funktionale Programmiersprache Elixir ebenfalls. Der Komfort: Code bleibt knapp und lässt sich leicht umbauen. Der Preis: Fehler werden erst sichtbar, wenn das Programm auf den unerwarteten Wert trifft.
Ein Beispiel zeigt, was sich bei Elixir mit dem am 3. Juni 2026 erschienenen Release 1.20 ändert. Die folgende Funktion nimmt eine Map entgegen, Elixirs Schlüssel-Wert-Struktur (geschrieben %{schlüssel: wert}, vergleichbar einem Dictionary in Python oder einem Hash in Ruby), und wandelt das darin enthaltene Feld age in eine Zeichenkette um:
Integer.to_string/1 ist dabei Elixirs übliche Schreibweise für eine Funktion: Modul, Funktionsname und nach dem Schrägstrich die Stelligkeit (Arity), also die Zahl der Argumente. Bis einschließlich Version 1.19 schwieg der Compiler zu diesem Code; dass age eine Zeichenkette statt einer Zahl enthält, fiel erst zur Laufzeit auf. Ab 1.20 erscheint eine Warnung beim Übersetzen:
Zwei Notationen darin sind erklärungsbedürftig (Typnamen tragen in Elixir stets leere Klammern). binary() ist Elixirs Typ für Zeichenketten, denn Strings sind in Elixir intern UTF-8-kodierte Binärdaten. Und die Ellipse in %{..., age: integer()} steht für beliebige weitere Schlüssel: Gemeint ist jede Map, die mindestens den Schlüssel age mit einem integer(), einer ganzen Zahl, enthält.
Niemand hat dem Compiler mitgeteilt, welchen Typ user.age haben soll. Er hat es selbst erschlossen: Integer.to_string/1 verlangt eine ganze Zahl, also muss das Feld age eine ganze Zahl enthalten, also muss jeder Aufrufer eine Map mit genau diesem Merkmal übergeben. Die Schlussfolgerung klingt trivial, aber sie steckt in keiner Typannotation, also keinem expliziten Typhinweis im Quelltext, wie ihn typisierte Sprachen verlangen (name: string in TypeScript, String name in Java). In Elixir 1.20 übernimmt der Compiler diese Arbeit von selbst.
Das dahinterstehende Typsystem, das seit Version 1.17 schrittweise in die Sprache einzog, analysiert inzwischen jedes Sprachkonstrukt. Es erkennt nicht nur fehlerhafte Argumente wie im Beispiel oben, sondern verfolgt auch, wie sich das Wissen über einen Wert durch mehrere Fallunterscheidungen hindurch verfeinert, und deckt dabei toten Code und widersprüchliche Zugriffe auf. Was abstrakt klingt, markiert einen Wendepunkt in der Geschichte von Elixir.
Sämtliche Vorteile des neuen Typsystems gibt es automatisch und ohne eigenes Zutun. An der Arbeitsweise muss sich nichts ändern, bestehender Code kompiliert unverändert weiter, niemand muss Typannotationen schreiben oder neue Syntax lernen; die zusätzliche Fehlersuche läuft bei jedem Übersetzen einfach mit.
Elixir ist eine funktionale, dynamisch getypte Sprache, die der Brasilianer José Valim 2012 veröffentlichte. Sie läuft auf der BEAM, der virtuellen Maschine von Erlang, und erbt von dort leichtgewichtige Prozesse im Millionenbereich (von der VM verwaltet, keine Betriebssystemprozesse) sowie eine ausfallsichere Laufzeit durch Supervisoren: überwachende Prozesse, die abgestürzte Teile des Systems automatisch neu starten.