2 Punkte von GN⁺ 2025-07-11 | 1 Kommentare | Auf WhatsApp teilen
  • Flix ist eine innovative Sprache, die funktionale Programmierung mit einem effektorientierten Modell kombiniert.
  • Sie erleichtert die Modellierung von Logikregeln und Datenabhängigkeiten und ist stark in der deklarativen Wissensrepräsentation.
  • Komplexe Abhängigkeitsbeziehungen und Prozessabläufe lassen sich prägnant als Code formulieren.
  • Dieser Ansatz bietet Effizienz bei Aufgaben der Algorithmusentwicklung und Schlussfolgerung.
  • Über Query-Funktionen lassen sich wissensbasierte Daten einfach erkunden.

Überblick über die Sprache Flix

  • Flix ist eine neue funktionale Sprache, die ein effektorientiertes Programmierparadigma einführt.
  • Programmierer können Systeme nicht als prozeduralen Code, sondern anhand logischer Beziehungen und Regeln beschreiben.
  • Mit Logikregeln (deklariert innerhalb von #{}) lassen sich komplexe Fertigungsszenarien wie Komponenten, Abhängigkeiten, Montagezeit und Liefertermine kompakt ausdrücken.

Deklarative Regeln und Datenmodellierung

  • Im Beispielcode werden Fakten und Regeln wie PartDepends, AssemblyTime, DeliveryDate, ReadyDate verwendet.
    • Mit PartDepends("Car", "Chassis") werden Abhängigkeitsbeziehungen zwischen Produkten definiert.
    • Mit AssemblyTime("Engine", 2) wird die Montagezeit einzelner Teile festgelegt.
    • Mit DeliveryDate("Piston"; 1) werden auch Liefertermine von Teilen angegeben.
  • Über die Logikregel ReadyDate lässt sich der endgültige Bereitstellungstermin für Teile mit definiertem Liefertermin oder montierte Bauteile berechnen.
  • Dadurch können Liefer- und Montagezyklen einzelner Teile einfach hergeleitet werden.

Effektorientierte Schlussfolgerung und Queries

  • Die Engine für logische Regeln von Flix kombiniert Effektorientierung mit Referenztransparenz und fördert dadurch ein intuitives und fehlerärmeres Programmdesign.
  • Mit der Query-Syntax lassen sich die Bereitstellungstermine aller Teile, die zu ReadyDate gehören, einfach ableiten.
  • Dieser Ansatz kann in vielen Bereichen eingesetzt werden, darunter Fertigung, Supply-Chain-Management und schlussfolgerungsbasierte Automatisierung.

Zusammenfassung und Vorteile

  • Flix kombiniert Effects mit schlussfolgerungsbasierter Logik auf Basis von Regeln und modelliert so prägnant die Beziehungen zwischen Komponenten und Prozessen in komplexen Systemen.
  • Im Vergleich zu bestehenden Sprachen bietet es besondere Vorteile bei logischer Klarheit und kompakterem Code.
  • Es kann passende Lösungen für viele moderne Softwareprobleme bieten, etwa in Knowledge Graphs, Workflow-Engines und Dateninferenzen.

1 Kommentare

 
GN⁺ 2025-07-11
Hacker-News-Kommentare
  • Ich bin sehr beeindruckt von der Tiefe und Breite dieser Sprache.
    Algebraische Datentypen, Logikprogrammierung, Mutabilität und andere essenzielle Funktionen sind alle von Anfang an enthalten.
    Am meisten gefiel mir in der Vergleichstabelle, dass eine einzelne ausführbare Datei zugleich Paketmanager, LSP und Compiler ist.
    Bei Haskell musste das LSP vieles zwischen ghc und den cabal-Dateien neu implementieren, außerdem wurde auch stack verwendet, sodass der offizielle Status des Paketmanagers etwas unklar war.
    Das soll keine Kritik an Haskell sein; es ist wirklich eine hervorragende Sprache.
    Schade nur, dass ihre besten Eigenschaften etwas versteckt wirken.
    Ich frage mich, wie komfortabel sich Flix auf der JVM mit Java und Ähnlichem integrieren lässt.
    Da JVM-Compiler die Typinformationen größtenteils ausradieren, finde ich das Konzept der "regions" in Flix positiv, weil es imperative Interaktion als Bürger erster Klasse unterstützt.
    Mit der JVM kann man zudem problemlos Standardbibliotheken von hoher Qualität im Wert von vielen Milliarden Dollar nutzen, was ein enormer Vorteil ist.
    Deshalb halte ich JVM oder .NET Core für mehr als 90 % aller Projekte für die vernünftigste Wahl.
    F# scheint die einzige wirklich vergleichbare Sprache zu sein.
    Es wäre großartig, wenn es ein Dokument gäbe, das die Grenzen der Interoperabilität zwischen Flix und der JVM zusammenfasst.
    Zur Referenz: Entsprechende Informationen gibt es hier.
    Grundsätzlich durchlaufen Flix-/Java-Werte Boxing und Unboxing.
    Außerdem sind Records Bürger erster Klasse.

    • Wenn dir gefällt, dass Paketmanager, LSP und Compiler alle in einer einzigen ausführbaren Datei stecken, wirst du Unison wahrscheinlich auch sehr mögen.

    • Der Teil zu Logikprogrammierung und Datalog wirkt eher wie ein Zusatz.
      Bei den anderen Funktionen ist klar zu sehen, wie sie die Typsicherheit im Codebestand verbessern, aber Logikprogrammierung ist schon eher ein Feature für eine Nische von Enthusiasten; vielleicht wäre es besser, wenn sie getrennt von der Sprache existierte.

    • Dass JVM-Compiler alle Typinformationen ausradieren, ist nicht ganz korrekt (anonyme Klassen behalten ihre Typparameter bei).
      Es gibt verschiedene Workarounds.
      Und aus Sicht des Compilers ist das eigentlich kein großes Problem.
      Man kann die Klassennamen mit angewendeten Typkonstruktoren einfach randomisieren und sie wie normale Klassen rendern.

    • F# unterstützt (noch) keine Typeclasses, deshalb gibt es viele Einschränkungen für monadenbasierte Programmierung.
      Wenn F# den Haskell-Stil mit Monaden überspringen und direkt zu algebraischen Effekten springen würde, würde das meiner Meinung nach besser zur Philosophie von F# passen.

    • Der Teil mit StringBuilder ist etwas enttäuschend.
      In dieser Hinsicht scheint es eher zur Java-Seite zu tendieren, deshalb bin ich nicht ganz überzeugt.
      Der Rest sieht auf den ersten Blick aber gut aus.

  • Aus Sicht der Sprachsemantik scheint die Semantik für Erweiterung/Einschränkung polymorpher Records Leijens Scoped-Label-Ansatz zu folgen (Link zum Paper).
    Wenn es zum Beispiel einen Record r1 = { color = "yellow" } gibt, kann man ihn mit r2 = { +color = "red" | r1 } erweitern.
    r2#color ergibt dann "red", und wenn man das Feld "color" wieder entfernt, erhält man r3 = { -color | r2 }.
    r3#color ergibt dann wieder den ursprünglichen Wert "yellow".
    Das erscheint mir deutlich vernünftiger als der frühere Stil, der ein extrem komplexes Typsystem brauchte, um zu verbieten, dass dasselbe Label-Feld zweimal hinzugefügt wird.

  • Ich frage mich, warum Aarhus (vor allem die Universität bzw. der Tech-Hub dort) einen so starken Einfluss auf die Forschung zu Programmiersprachen hat.
    C++, C#/Typescript, Dart – alle haben starke Wurzeln in dieser kleinen Region Dänemarks.
    Es ist keine typische Eliteuniversität wie Ivy League oder Oxbridge und auch nicht wie Delft oder INRIA.
    Was macht es so besonders? Liegt es am Wasser, oder gibt es einen anderen Grund? Reine Neugier.

    • Eine Sache dazu: C# wurde von Anders Hejlsberg entwickelt, und er hat an der DTU in Kopenhagen studiert.
      Auch Turbo Pascal stammt von ihm, und Borland wurde ebenfalls von einem Dänen gegründet.
      Allgemein ist Dänemark stark in der Theorie von Programmiersprachen.
      Zum Beispiel stammen auch die Autoren des Standard-Lehrbuchs für Graduierte zur statischen Programmanalyse (Nielson & Nielson) aus Dänemark.
      Mads Tofte hat bedeutende Beiträge zu Standard ML geleistet.
      Aarhus ist vielleicht nicht auf Ivy-League- oder Oxbridge-Niveau, aber dennoch eine ausgezeichnete Universität.
      In Europa gibt es dutzende solcher Hochschulen, die zwar weniger berühmt sind, aber eine hervorragende Qualität in Lehre und Forschung haben.

    • Aarhus hat eine starke Tradition in Logik, Typentheorie sowie funktionalen und objektorientierten Sprachen.
      Viele Forschende, die in diesen Bereichen Einfluss hatten, stammen aus Aarhus.
      Außerdem fühlt es sich so an, als sei die Forschung zu Programmiersprachen weltweit stark US-zentriert.
      Institutionen wie Aarhus betreiben deutlich weniger Marketing und Selbst-PR und konzentrieren sich eher auf gute Forschung.
      Das macht sie nicht besser oder schlechter, erschwert aber die globale Aufmerksamkeit.

  • Flix wirkt weiterhin wie die durchdachteste Sprache unter den ML-artigen Sprachen.
    Die Kombination aus funktionalem, imperativem und logischem Paradigma sowie ein polymorphes Typ- und Effektsystem mit Datalog-Constraints als Bürger erster Klasse sind wirklich einzigartig.
    Dass auf Typebene strikt zwischen reinem und unreinem Code unterschieden wird, fühlt sich als frischere und leichter zu inferierende Alternative zu Monaden an.
    Auch die Philosophie "eine Sprache, keine Flags nötig" und der Anspruch, nur Compile-Time-Fehler zuzulassen, gefallen mir, weil das alles einfach und vorhersagbar macht.
    Dass Flix vollständige Tail-Call-Elimination implementiert hat, obwohl die JVM selbst Tail-Recursion-Elimination nicht nativ unterstützt, ist eine bemerkenswerte technische Leistung.
    Mich würden Erfahrungen von Leuten interessieren, die Flix tatsächlich in Produktion oder in der Forschung einsetzen.
    Besonders spannend wären Berichte aus Logikprogrammierung oder Concurrency – etwa über Schwierigkeiten mit der Closed-World-Assumption oder der fehlenden Unterstützung für Ausnahmen sowie über Unterschiede zur Integration von Datalog in anderen Logiksprachen wie Prolog.

  • Als ich mir Flix vor einiger Zeit angesehen habe, fand ich es so interessant, dass ich sogar einen Artikel mit dem Titel "Flix für Java-Programmierer" geschrieben habe.
    Inzwischen ist er zwar etwas veraltet und müsste aktualisiert werden, aber ...
    Falls es jemanden interessiert: hier.

    • Der Blogbeitrag ist wirklich großartig.
      Mit Erlaubnis würde ich ihn gern in die offizielle Sammlung von Flix-Blogposts aufnehmen (Link).
      Seit diesem Beitrag hat sich die Sprache Flix stark weiterentwickelt.
      Vor allem das Effektsystem wurde stark ausgebaut, und es gab Verbesserungen bei der Java-Interoperabilität sowie Syntax-Updates.

    • Der Blog ist wirklich eine Schatzkammer.
      Er wirkt wie eine ausgefeiltere Version von Gedanken, die mich schon lange beschäftigt haben.
      Ich freue mich darauf, alles zu lesen.

  • Cool, dass auch HKTs unterstützt werden.
    Ich sehe aber keine Erklärung zu Typeclasses und frage mich deshalb danach.
    Wenn zusätzlich noch Typeclasses und Scala-artige Makros unterstützt würden, würde ich gern meine eigenen Bibliotheken (distage, izumi-reflect, BIO) nach Flix portieren und sogar ernsthaft überlegen, von Scala zu Flix zu wechseln.
    Später habe ich entdeckt, dass Typeclasses hier offenbar Traits genannt werden.
    Bei Makros frage ich mich weiterhin, wie es damit aussieht.
    Außerdem finde ich es schade, dass Flix keine explizite nominale Vererbung unterstützt.
    Nicht einmal die harmloseste Form von trait aus Scala ist erlaubt.
    Typeclasses können Interfaces nicht ersetzen, und ohne diese Abstraktion lassen sich viele nützliche Dinge entweder gar nicht umsetzen oder der Code wird unschön.

    • Flix unterstützt Typeclasses (hier trait genannt) zusammen mit HKT, Associated Types und Associated Effects.
      Traits können auch Standardimplementierungen für Funktionen liefern, die in Instanzen überschrieben werden können.
      Vererbung gibt es in Flix überhaupt nicht.
      Traits werden nur zur Compile-Time verwendet und anschließend monomorphisiert, sodass kein Runtime-Overhead entsteht.
      Der Flix-Inliner optimiert auch innerhalb von Traits und entfernt sogar Closures aggressiv.
      Zum Beispiel werden Higher-Order Functions oder Pipelines auf Bytecode-Ebene zu ganz normalen Schleifen, ohne Closure-Allokationen oder indirekte Aufrufe.
      Flix unterstützt derzeit noch keine Makros.
      Wegen der Erfahrungen mit ihrem (oft missbräuchlichen) Einsatz in anderen Sprachen scheint man ihre Einführung eher zu scheuen.
      Es werden gerade neue Bibliotheksautor:innen gesucht; falls du Interesse hast, komm gern im Gitter-Kanal vorbei.
  • Zu dem Abschnitt "Von Flix nicht unterstützte Funktionen" in der offiziellen Dokumentation:
    Dort gibt es den Punkt "No Code Before Main".
    In der eigentlichen Erklärung steht jedoch: "Flix führt vor main keinen Code aus und hat keinerlei statische Initialisierer oder Ähnliches."
    Ich denke, der Funktionsname wäre als "Code Before Main" präziser.

  • Ich frage mich, warum man in Flix explizit kennzeichnen muss, dass eine Funktion rein ist.
    In fast allen Fällen sollte statische Analyse das doch ausreichend inferieren können – warum also diese Anforderung?

    • Soweit ich weiß, sorgt die Kennzeichnung einer Funktion als rein dafür, dass der Compiler dies garantiert.

    • Wenn man den Satz "Flix verfolgt die Reinheit jedes Ausdrucks im Programm präzise" zusammen mit dem Beispiel einer Funktionsdefinition ohne Kennzeichnung für rein/unrein liest,
      entsteht der Eindruck, dass der Compiler in den meisten Fällen Reinheit automatisch inferieren kann und die Markierung für rein/unrein eher optional ist.

  • Die Flix-FAQ (Link) beginnt ganz normal und wird dann immer unterhaltsamer.
    Ein paar lustige Beispiele:

    • F: Ergibt Division durch 0 wirklich 0?<br> A: Ja. Aber sich nur darüber Sorgen zu machen, ist ungefähr so, als würde man bei einem Raumschiff nur über die Farbe der Sitze diskutieren.
    • F: "Diese Website benötigt JavaScript"<br> A: Menschen, die den Einsatz von JavaScript kritisiert haben: [1],[2],[3],[4],[5], Menschen, die tatsächlich Hilfe beim Refactoring zu HTML angeboten haben: 0
    • F: Ich bin enttäuscht, dass statt meines Lieblingsfeatures Y das Feature X eingebaut wurde<br> A: Schade
    • F: Die schlimmste Syntax, die ich je bei einer funktionalen Sprache gesehen habe. Eine Mischung aus Semikolons, geschweiften Klammern und Symbolchaos. Als hätten Scala, Java und Haskell mitten in Tschernobyl einen One-Night-Stand gehabt<br> A: Ist das nicht eher eine beeindruckende Leistung?
  • Ich frage mich, ob Code-Agenten, die mit dieser Sprache kompatibel sind, schon gut funktionieren oder ob man doch selbst denken muss.
    Das ist halb im Scherz gemeint, aber die Sprache sieht tatsächlich großartig aus, was mich traurig macht.
    Wenn LLMs die Einführung neuer Sprachen eher behindern, wie löst man dieses Problem dann?

    • Mein Gefühl ist eher, dass LLMs die Hürde für die Einführung neuer Sprachen senken werden.
      Code aus Standardbibliotheken reicht aus, damit ein LLM neue Syntax lernt, und selbst wenn nicht, kann ein Agent auch aus den Compiler-Ausgaben lernen.
      Das Portieren von Code selbst ist keine Aufgabe, die besonders viel Kreativität verlangt, sondern eine klar definierte Arbeit – also genau die Art von Automatisierung, bei der LLMs als Erstes glänzen werden.
      In Zukunft sollten wir unseren Kopf eher dafür einsetzen, ernsthaft darüber nachzudenken, warum wir etwas tun und welche Auswirkungen es auf die Welt hat.

    • Ich habe ganz brauchbare Ergebnisse bekommen, indem ich im Prompt explizit verlangt habe, die Index-/Dependent Types von Idris zu verwenden.
      (Ohne solche Hinweise ist meist bei GADTs Schluss.)