2 Punkte von GN⁺ 2025-12-14 | 1 Kommentare | Auf WhatsApp teilen
  • Der Autor löste die 12 Tage von Advent of Code 2025 mit Gleam und war besonders von den Fehlermeldungen auf Rust-Niveau sowie dem pipelineorientierten funktionalen Stil der Sprache beeindruckt
  • Eingebaute Funktionen wie echo, fold_until und list.transpose vereinfachten Debugging und das Lösen von Kombinationsproblemen, während die Sicherheit durch Option-Typen bei der Verarbeitung von Grid-Puzzles nützlich war
  • Als Nachteile wurden genannt, dass die Standardbibliothek weder Datei-I/O noch reguläre Ausdrücke enthält, außerdem Einschränkungen beim Listen-Pattern-Matching und explizite Vergleichssyntax, die bei wiederholter Nutzung umständlich wirkt
  • Wegen Unterschieden bei der Integer-Verarbeitung zwischen Erlang VM und JavaScript-Target war der Einsatz von bigi nötig; einige Puzzles wurden außerdem durch den Aufruf externer Tools wie glpsol gelöst
  • Insgesamt betont der Autor, dass der Wechsel zu funktionalem Denken die Puzzle-Lösungen klarer gemacht hat, und äußert Vorfreude darauf, Gleam in echten Projekten wie etwa der Entwicklung eines Webservers einzusetzen

Advent of Code 2025 und die Wahl von Gleam

  • Der Autor, der Advent of Code jedes Jahr vollständig absolviert hat, entschied sich dieses Jahr für die Sprache Gleam und löste damit die Puzzles über 12 Tage
    • Die Veranstaltung wurde dieses Jahr von 25 auf 12 Tage verkürzt; die einzelnen Aufgaben waren anspruchsvoll, aber gut zum Lernen geeignet
  • Da der Fortschritt durch die Puzzles schnell war und komplexe Probleme auftauchten, bevor das Toolset vollständig stand, ergab sich eine ideale Umgebung zum Lernen einer neuen Sprache

Sprachliche Stärken von Gleam

  • Kennzeichnend sind die knappe Syntax, nützliche Compiler-Fehlermeldungen und hilfreiches Feedback auf Rust-Niveau
  • Der auf dem Pipe-Operator basierende funktionale Stil passt gut zur Struktur von AoC-Aufgaben (Parsing → Transformation → Fold)
  • Die Gleam-Erweiterung für IntelliJ und der LSP funktionierten stabil, was für eine angenehme Entwicklungsumgebung sorgte
  • Funktionale Programmierung (FP) lenkt das Denken weg von imperativem Code hin zu einer Beschreibung des eigentlichen Problems

Wichtige Funktionen und Beispiele aus dem Code

  • echo: eine einfache Ausgabefunktion, mit der sich Werte mitten in einer Pipeline prüfen lassen; Debugging ist damit ohne String-Formatierung möglich
    • Als Nachteil wird erwähnt, dass es keine String-Interpolation gibt, wodurch bei der Texterzeugung viele <>-Operationen nötig werden
  • Option-Typen (dict.get): ermöglichen bei Grid-Puzzles eine sichere Nachbarschaftssuche ohne explizite Bounds-Checks
  • Listen-Utilities
    • list.transpose: vereinfacht Puzzle-Strukturen durch Matrix-Transposition
    • list.combination_pairs: erzeugt Paare von 3D-Punkten in einer Zeile ohne verschachtelte Schleifen
    • fold_until: eine Fold-Funktion mit frühem Abbruch, sobald eine Bedingung erfüllt ist; effizient für wiederholte Berechnungen in Puzzles

Einschränkungen und Unbequemlichkeiten in Gleam

  • Kein Datei-I/O in der Standardbibliothek, stattdessen wurde das Paket simplifile verwendet
  • Auch für reguläre Ausdrücke ist eine externe Abhängigkeit (gleam_regexp) nötig
  • Einschränkungen beim Listen-Pattern-Matching: Formen wie [first, ..middle, last] sind nicht möglich
  • Explizite Behandlung von Vergleichen: Dafür muss der Typ order verwendet werden, was einfache Vergleiche unnötig ausführlich macht

Fortgeschrittene Nutzung und puzzlebezogene Beispiele

  • bigi: wurde beim JavaScript-Target verwendet, um Integer-Overflows zu vermeiden
  • XOR-Bitmaske: In Tag 10-1 wurde ein Lichtschalterproblem effizient durch Modellierung mit XOR gelöst
  • Aufruf von glpsol: In Tag 10-2 wurde zur Lösung linearer Gleichungen eine LP-Datei erzeugt und ein externer Befehl ausgeführt
  • Memoization-Key: In Tag 11-2 wurden Knoten und Zustand gemeinsam als Schlüssel verwendet, wodurch die Berechnung sofort abgeschlossen werden konnte
  • Das letzte Puzzle hing von Annahmen über die Eingabe ab und wurde mit einem einfachen Flächenvergleich (heuristic_area <= max_area) gelöst

Fazit und Ausblick

  • Gleam zeigt trotz der Grenzen seiner Standardbibliothek Stärken bei Sicherheit und Ausdruckskraft
  • Pipelines, Option-/Result-Typen, Listenfunktionen und fold_until machen das Lösen von Puzzles klarer
  • Künftig ist der Einsatz in realen Projekten wie der Entwicklung eines Webservers geplant; auch beim Advent of Code im nächsten Jahr möchte der Autor Gleam weiter verwenden
  • Der gesamte Quellcode ist im GitHub-Repository veröffentlicht (tymscar/Advent-Of-Code/2025/gleam/aoc/src)

1 Kommentare

 
GN⁺ 2025-12-14
Hacker-News-Kommentare
  • Gleam ist wirklich eine wunderschöne Sprache. Ich wünschte, Elixir würde sich beim Typsystem in diese Richtung entwickeln.
    Gleam läuft ebenfalls auf der Erlang-VM BEAM, wodurch Nebenläufigkeit und Queue-Verarbeitung sehr einfach werden.
    Auch das Ökosystem ist großartig. Allerdings mache ich mir Sorgen, dass die Sprachentwicklung seit 2021 im Zeitalter der LLMs ins Stocken geraten ist.
    Trotzdem ist Gleam noch kurz vor dem Zuschlagen dieses Fensters gut hineingekommen, und ich hoffe, dass die LLMs bald aufholen werden.

    • Ich frage mich, warum du denkst, dass LLMs die Sprachentwicklung zum Stillstand bringen. Aktuelle Modelle enthalten Wissen bis in dieses Jahr, und neue Sprachen lernen sie mit ein paar Beispielen schon ziemlich gut.
      Da sich Sprachen syntaktisch oder philosophisch ohnehin nicht völlig unterscheiden können, dürfte das kein großes Problem sein.
    • Es ist nicht ganz korrekt zu sagen, dass Gleam auf OTP gebaut ist. Die Erlang-VM ist BEAM, und OTP ist eine Sammlung von Bibliotheken und Entwurfsprinzipien für Erlang.
      Gleam bietet selbst eine typsichere OTP-Teilmenge. Siehe dazu die Bibliothek gleam-lang/otp.
    • Genau, die Erlang-VM ist BEAM, nicht OTP. Gleams OTP-Implementierung ist noch nicht so ausgereift wie die von Elixir oder Erlang.
    • Ich habe kürzlich auch mein erstes Projekt mit Elixir und LLM-Funktionalität gebaut, und ich habe eher das Gefühl, dass dieser Trend die Sprachadoption fördern könnte.
    • Elixir führt schrittweise auch set-theoretic typing ein. Relevante Dokumentation: gradual-set-theoretic-types
  • Ich habe dieses Jahr den Advent of Code mit Gleam gelöst und war ziemlich beeindruckt.
    Zu den Vorteilen zählen die gute Performance und ein erstaunlich leistungsfähiger Language Server. Autoformatierung, automatische Imports, Unterstützung beim Pattern Matching – die Entwicklererfahrung ist hervorragend.
    Nachteile sind, dass der Formatter den Code zu stark in die Vertikale zieht, und dass wegen des Fokus auf Einfachheit viel Wiederholung wie list.map entsteht. Außerdem ist das Bibliotheksökosystem noch etwas dünn.

    • Ich war auch von der Performance überrascht. Nicht auf C-Niveau, aber deutlich schneller als erwartet. Der Language Server funktioniert außerdem in fast allen IDEs gut.
      list.map lässt sich mit import gleam/list.{range, map} verkürzen. Auch das Portieren von C-Bibliotheken wäre spannend.
    • Mit den Nachteilen kann man leben, aber dass es if/else oder guards nicht gibt, ist unpraktisch. Boolesche Verzweigungen werden dadurch zu ausschweifend.
    • Ich habe AoC mit F# gemacht, und das fühlte sich ähnlich an. Namespace-Wiederholungen wie List.map verschlechtern die Discoverability.
    • Die Argumentformatierung liegt wahrscheinlich am Prettier-Algorithmus. Trotzdem finde ich das viel besser als das Binpacking von clang-format.
  • Ich mag Gleam, aber die Einschränkungen bei rekursiven Funktionsaufrufen sind schade. Interne Funktionsaufrufe sind nicht frei möglich.
    Syntaktisch ist es weniger elegant als Scheme, konzeptionell einfacher als Erlang. Statische Typisierung ist dafür ein Pluspunkt.
    Ich habe auch OCaml verwendet, aber wegen Problemen mit Lockfiles in opam war die Umgebung nicht besonders reproduzierbar. Ich wünschte, das SML-Ökosystem wäre größer.

    • Ich sehe das ähnlich. Haskell ist theoretisch großartig, aber schon ein einfaches Hello World hat einen hohen Ressourcenverbrauch.
      Idris 2 hat abhängige Typen und ein elegantes Design, aber ein kleines Ökosystem, und PureScript ist praktischer als Haskell, hängt aber an der JS-Runtime.
    • Wenn du die ML-Familie magst, empfehle ich ReScript v12. Es liegt gut ausbalanciert zwischen OCaml und Gleam.
  • Beim echo-Feature dachte ich mir, dass ich so eine Zwischenergebnisanzeige gern standardmäßig in Debuggern hätte.
    Es wäre schön, Zwischenergebnisse von Array-Slices oder Filter-Ketten sehen zu können, ohne den Code ändern zu müssen.
    Außerdem halte ich es für ineffizient, zweidimensionale Arrays als Grid zu verwenden. Ein eindimensionales Array plus Grenzinformationen ist sicherer und effizienter.

  • Ich kenne mich mit Gleam nicht gut aus, aber bei list.map(fn(line) { line |> calculate_instruction })
    müsste man nicht einfach list.map(calculate_instruction) schreiben können?

    • Genau, ich habe auch schon öfter komplexere Verarbeitung entfernt und dann diese Form stehen lassen.
    • Ja, genau so ist es.
  • Gleam ist eine großartige Sprache. Mich hat sie nicht besonders gepackt, aber ich freue mich, dass andere Spaß damit haben.
    Ich könnte mir vorstellen, dass die Kombination Gleam + Lustre zu einem neuen Elm werden könnte.

    • Als Backend-Entwickler fand ich Elm attraktiv, habe mich aber wegen der Konflikte mit dem Ersteller und dem Ausbleiben neuer Releases davon entfernt. Die Architektur war trotzdem auch in anderen Projekten nützlich.
    • Ich habe kürzlich ebenfalls eine kleine App mit Gleam + Lustre gebaut, und das lief viel besser als mit Elm + PostgREST. Ich werde es jetzt auch für größere Projekte einsetzen.
    • Ich habe mir Lustre angesehen, aber das Ökosystem ist noch klein. Es gibt nicht einmal Beispiele für Authentifizierung, deshalb bin ich bei LiveView gelandet. Trotzdem ist die Ergonomie gut, und ich hoffe, dass es wächst.
  • In der aktuellen LLM-Ära frage ich mich, ob es überhaupt noch sinnvoll ist, neue Sprachen zu lernen.
    Wenn eine Sprache von LLMs nicht gelernt wurde, mache ich mir Sorgen, dass ihr Nutzen als Werkzeug sinkt.

    • Langfristig würde das bedeuten, dass LLMs als Ziel einer allgemeinen Intelligenz gescheitert sind, wenn sie neue Sprachen nicht lernen können.
    • Vor ein oder zwei Jahren war das noch eine Sorge, aber heute schreibt Claude Code auch Elixir ziemlich gut. Selbst wenig Trainingsdaten sind kein Problem.
    • Claude kommt auch mit Gleam gut zurecht. Die Dokumentation und die Qualität der Diagnosemeldungen sind gut, deshalb können LLMs es leicht lernen. Es liefert Diagnosen auf Rust-Niveau.
      Swift dagegen hat eine komplexe Syntax und ist für LLMs schwerer zu handhaben.
    • Wenn man Sprachen als Werkzeug betrachtet, könnte fehlende Marktnachfrage die größere Einschränkung sein.
    • Ich hoffe, dass neue Sprachen nicht wegen der Grenzen von LLMs zum Stillstand kommen.
  • Als ich mir Gleam früher angesehen habe, schien es keine dynamische Disposition zu geben, also keine Interfaces oder Type Classes. Mich würde interessieren, wie das heute aussieht.

    • Üblicherweise löst man das, indem man „eine Funktionsstruktur übergibt“. Dieser explizite Ansatz ist eher angenehm, weil man damit die Komplexität von Generics vermeidet.
    • Gleam unterstützt First-Class Functions, daher ist dynamische Disposition möglich. Type Classes oder Interfaces lassen sich letztlich auch über Higher-Order Functions ausdrücken.
  • [first, ..rest] oder [first, second] sind möglich, aber [first, ..middle, last] nicht.
    Vermutlich wurde das absichtlich verhindert, weil es zu teuer wäre.

  • Zum Glück war die Blogtitel-Polizei schnell zur Stelle.
    Relevanter Link