1 Punkte von GN⁺ 2026-01-09 | 1 Kommentare | Auf WhatsApp teilen
  • Der Schlüssel zur Produktivität beim Programmieren liegt weniger in der Sprache selbst als in einem reichen Bibliotheks-Ökosystem
  • Frameworks wie Ruby on Rails, die fortgeschrittene Sprachfunktionen nutzen, bieten selbst Nicht-Spezialisten hohe Produktivität
  • Wegen struktureller Grenzen von Sprachen ist es jedoch schwierig, ein Framework auf dem Niveau von Rails in Java oder C umzusetzen
  • Sprachdesign bestimmt direkt Form und Komplexität der Bibliotheken, die geschrieben werden können, und genau darin liegt der eigentliche Zweck der Weiterentwicklung von Sprachen
  • Die Sprache Stanza zeigt aus dieser Perspektive, wie wichtig Sprachdesign ist, um leistungsfähige und leicht nutzbare Bibliotheken zu ermöglichen

Die Beziehung zwischen Programmiersprachen und Bibliotheken

  • Die meisten Programmiersprachen besitzen ähnliche Grundelemente wie Variablen, Arrays, Schleifen und Funktionen
    • Einige Sprachen bieten fortgeschrittene Funktionen wie Funktionen erster Klasse oder Coroutines, doch Nicht-Spezialisten nutzen diese kaum
  • Für viele Entwickler ist der entscheidende Produktivitätsfaktor nicht die Sprache, sondern die Bibliothek
    • Ruby on Rails macht es zum Beispiel leicht, datenbankgestützte Webanwendungen zu erstellen
    • Dank Rails ist die Präferenz für das Framework oft größer als die für die Ruby-Sprache selbst

Das Zusammenspiel von Ruby on Rails und Sprachfunktionen

  • Rails nutzt verschiedene Funktionen von Ruby wie Metaprogrammierung, Auswertung zur Laufzeit, Funktionen erster Klasse und Garbage Collection
    • Beispiel: ActiveRecords verwendet Metaprogrammierung, das Template-System nutzt Laufzeitauswertung
    • Die Ereignisbehandlung wird umgesetzt, indem Funktionen erster Klasse als Callbacks übergeben werden
  • In Java oder C fehlen diese Fähigkeiten, sodass die Umsetzung eines Frameworks auf Rails-Niveau unmöglich ist
    • Die Metaprogrammierung in Java ist nicht mächtig genug, um ActiveRecords zu implementieren
  • Daher ist Rails nur dank der Struktur der Ruby-Sprache möglich, und Sprachdesign bestimmt die Möglichkeiten von Bibliotheken

Sprachdesign bestimmt die Form von Bibliotheken

  • Die Sprache C unterstützt Wiederverwendung nur über Funktionsdeklaration und -aufruf, daher bestehen die meisten C-Bibliotheken aus Sammlungen von Funktionen
  • Ruby unterstützt Funktionen erster Klasse und kann dadurch „welche Aktion bei einem Button-Klick ausgeführt werden soll“ knapp ausdrücken
    • In Java muss man dagegen eine Handler-Klasse definieren, wodurch der Code komplexer wird
  • Die Ausdrucksstärke einer Sprache bestimmt Struktur und Benutzbarkeit von Bibliotheken unmittelbar

Interaktive Software und das Aufkommen erweiterbarer Frameworks

  • Im Batch-Computing der 1970er Jahre reichten funktionszentrierte Bibliotheken aus
  • In moderner interaktiver Software sind erweiterbare Bibliotheken erforderlich
    • In GUI- oder ereignisbasierten Systemen wird eine Struktur benötigt wie: „Führe meinen Code aus, wenn der Benutzer klickt“
  • Java und C++ unterstützen Erweiterbarkeit durch Vererbung und Methodenüberschreibung, und diese Struktur entwickelte sich zu Frameworks

Hintergrund des Stanza-Designs und Grenzen von Sprachen

  • Die Motivation für das Design von Stanza entstand aus der Schwierigkeit, in Java leicht nutzbare Bibliotheken für die Spieleprogrammierung zu schreiben
    • In Java musste Nebenläufigkeit als Zustandsmaschine (state machine) ausgedrückt werden
    • Scheme unterstützt Continuations und erlaubt dadurch eine intuitivere Umsetzung
  • Scheme unterstützt jedoch keine statische Typprüfung, wodurch Debugging weniger effizient ist
    • Die meisten heutigen Sprachen können ihr Typsystem nicht per Bibliothek erweitern
  • Stanza bietet ein optionales Typsystem, Garbage Collection und ein auf Multimethoden basierendes Objektsystem
    • Ein benutzerdefiniertes Objektsystem lässt sich jedoch nicht neu schreiben

Ziel von Sprachen und Forschungsrichtungen

  • Das Ziel allgemeiner Programmiersprachen ist es, die Erstellung leistungsfähiger und leicht nutzbarer Bibliotheken zu unterstützen
    • Je mächtiger eine Sprache ist, desto knapper wird die Nutzung von Bibliotheken
  • Wenn Code gut entworfene Bibliotheken verwendet, besitzt er eine Natürlichkeit, als würde man einem Kollegen Anweisungen geben
  • Racket, Shen und Forschungen zu Metaobjektprotokollen untersuchen erweiterbare Typ- und Objektsysteme
  • Letztlich unterscheiden sich Sprachen danach, „welche Bibliotheken man nutzen kann und welche nicht
  • Hinter eleganten Bibliotheken stehen jahrzehntelange Forschung und Designarbeit an Programmiersprachen

1 Kommentare

 
GN⁺ 2026-01-09
Hacker-News-Kommentare
  • Das beste Beispiel ist Prolog. Es wird oft als die repräsentative Sprache des logischen Programmierens bezeichnet, ist aber in der Praxis kaum mehr als eine Sammlung verschiedener Algorithmen und könnte als Bibliothek in jeder Sprache implementiert werden. Es würde ausreichen, nur die syntaktische Ausdrucksform von Prolog an die jeweilige Syntax der einzelnen Sprachen anzupassen

    • Der Kern von Prolog ist nicht der Algorithmus, sondern die deklarative Beschreibung logischer Regeln. Definiert man zum Beispiel die Regel „Großeltern sind die Eltern der Eltern“, kann man damit Großeltern finden oder umgekehrt Elternbeziehungen ableiten. Gerade diese bidirektionale Inferenz macht den Reiz von Prolog aus. Natürlich braucht man, wenn man so etwas in einer allgemeinen Sprache nachbilden will, nebenwirkungsfreien Code und ein eingeschränktes DSL. Da sprachübergreifende Aufrufe wie bei PyTorch oder TensorFlow, die CUDA aus Python heraus nutzen, ebenfalls möglich sind, halte ich auch eine sprachunabhängige Struktur für gut machbar
    • Die Syntax von Prolog ist eine Teilmenge der First Order Logic, und Variablen bekommen keine festen Werte zugewiesen, sondern es wird über Mengen möglicher Werte gesucht, bis die Bedingungen erfüllt sind. Eine Prolog-Engine leistet mehr als ein einfacher Bibliotheksaufruf — zum Beispiel komprimierte Darstellung des Suchraums, parallele Ausführung und automatisches Pruning. Deshalb wird Prolog meist als Backend-Service eingesetzt oder per Code-Generierung integriert. Prolog ist besonders stark bei Planung, Constraint Solving, Theorembeweisen, kombinatorischen Tests und Preis-Modellierung. Deshalb halte ich es für schwer, Prolog einfach als „eine Sprache, für die eine Bibliothek genügt“ zu betrachten
    • Nach derselben Logik könnte man auch sagen, dass objektorientale Features nicht wirklich als Sprachelemente nötig sind, weil man sie mit Closures nachbilden kann. Aber die Ausdruckskraft einer klaren Syntax hat eben echte Vorteile
    • Um relationales Programmieren wie in Prolog als Bibliothek umzusetzen, müsste die Sprache Symbole und Variablenmanipulation als First-Class-Objekte unterstützen. Bei Lisp-artigen Sprachen ist das noch am ehesten möglich, in allgemeinen Sprachen leidet die Nutzbarkeit aber stark. Als ich einmal mit Bob Harper darüber sprach, sagte er: „Mach einfach eine neue Sprache“ — und das klang ziemlich überzeugend
    • Ich möchte Prolog lernen, aber es ist schwer, Material auf mittlerem Niveau zwischen Einsteiger-Tutorials und fortgeschrittenen Beispielen zu finden. Ich möchte Sudoku-Varianten mit Prolog lösen, doch bestehende Beispiele sind so stark optimiert, dass es schwer ist, verallgemeinerte relationale Definitionen daraus zu lernen. Mich interessiert besonders, wie man Situationen modelliert, in denen einige Regeln falsch sein könnten. Als Referenz schaue ich mir gerade das Sudoku-Beispiel von SWI-Prolog an
  • Vor zehn Jahren war ich ein Scala-Fan. Das Konzept einer „Scalable Language“, in deren Typsystem man DSLs bauen kann, fand ich sehr reizvoll. Aber als die Community anfing, es wie ein Haskell auf der JVM zu verwenden, verlor ich das Interesse. Heute hoffe ich, dass Technologien wie WASM oder Graal mehr Flexibilität bei der Sprachwahl bringen. Oft reicht JS aus, aber es ist gut, jetzt auch die Option zu haben, bei Bedarf eine Low-Level-Sprache wie Rust zu verwenden

    • Ich denke auch, dass das größte Problem von Scala der Missbrauch von DSLs ist. Nicht nur bei der Sprache selbst, sondern auch bei Test-Frameworks hat man oft das Gefühl, noch eine weitere Sprache lernen zu müssen. Natürlich ist es beeindruckend, Hadoop MapReduce in einer einzigen Zeile ausdrücken zu können, aber für die meisten Arbeiten ist das übertrieben. Dazu kommt, dass Scala-Entwickler oft keine „langweiligen“ Programme schreiben wollen. Ich habe viele Fälle gesehen, in denen jemand unbedingt etwas besonders Elegantes bauen wollte, dann aber die Wartungshölle hinterließ und verschwand
    • Nicht die gesamte Scala-Community orientiert sich an Haskell. Nur einige Typ-Magier zeigen diese Tendenz. Scala ist auch als schlichtes „besseres Java“ schon hervorragend. Man kann die Vorteile funktionaler Programmierung nutzen, ohne dass es zu belastend wird
    • Haskell wird ohnehin oft als Sprache zum Bauen von DSLs verwendet. Gute Beispiele sind Haxl von Meta oder das Musik-DSL TidalCycles. Allerdings bringen Bibliotheken auf Basis höherer Typsysteme oft starke Performance-Einbußen mit sich und sind unnötig komplex
    • Hast du schon einmal Clojure(Script) ausprobiert? Wie es sich für eine Lisp-Familie gehört, ist dort Bottom-up-Programmierung möglich, also das Erweitern der Sprache passend zum Problem. Paul Graham betont diesen Ansatz auch in On Lisp. Empfehlenswert ist auch der Vortrag Bottom Up vs Top Down Design in Clojure
    • Ich habe erst vor Kurzem angefangen, Scala zu lernen, und mir gefällt es auch aus Sicht der funktionalen Programmierung sehr. Ich halte es für allgemein genug einsetzbar, dass es weit über den Bau von DSLs hinaus nützlich ist. Mich würde interessieren, ob du Punkte siehst, in denen Scala schwächelt
  • Es wäre schön, bash durch eine typisierte Skriptsprache ersetzen zu können. Ich habe einmal ein einfaches JSON-Parser-Skript in Elixir geschrieben, und das war ziemlich angenehm

    • Hast du schon Nushell ausprobiert? Dinge, für die man früher eine „echte Sprache“ gebraucht hätte, lassen sich dort oft in einer einzigen Zeile erledigen. Zum Beispiel kann man eine Pipeline zum Sortieren einer Dateiliste und zur Ausgabe als JSON sehr einfach schreiben
    • Eigentlich kann man mit einem shebang in vielen Sprachen Skripte schreiben. Zum Beispiel geht das mit C#, Java und Go. Mit Scriptisto kann man Shebang-Skripte in fast jeder Sprache schreiben
    • Auch OCaml lässt sich wie eine Skriptsprache verwenden. Mit #!/usr/bin/env ocaml kann man es direkt ausführen. Allerdings gibt es keine Funktion, die in einer einzelnen Datei externe Abhängigkeiten automatisch installiert
    • Auch für Go gibt es einen Trick, um shebang nachzuahmen. Die Diskussion dazu gibt es hier
    • Für Alltags-Skripting sind auch Python oder PowerShell gute Optionen
  • Sprache und Bibliothek sind nicht gegenseitig ausschließend. Manche Bibliotheken funktionieren faktisch wie eine Sprache, und umgekehrt werden manche Sprachen für bestimmte Bibliotheken entworfen. Julia ist zum Beispiel ein guter Fall für die Balance zwischen Performance und Nutzbarkeit. Man kann Hochleistungscode direkt in Julia schreiben und durch typ-spezialisierte Kompilierung auf JIT-Niveau optimierte Ausführung erhalten. Das Aufrufmodell ist einfach, intern arbeitet das System aber sehr ausgefeilt

    • Genau, der eigentliche Punkt war am Ende, dass man sowohl Sprache als auch Bibliothek braucht
  • Raku ist als Struktur entworfen, die mehrere Teilsprachen (slangs) verbindet. Reguläre Ausdrücke, PEG, Quoting und anderes werden jeweils als eigene Mini-Sprachen behandelt, und mit Slangify kann man leicht ein eigenes DSL hinzufügen

    • Persönlich mag ich bei Raku aber die Syntax nicht, bei der der Typ hinter dem Variablennamen steht, deshalb bevorzuge ich es nicht
  • Ein Senior-Entwickler sagte einmal: „Wenn ich Rails im Lebenslauf sehe, werfe ich ihn sofort weg.“ Da habe ich wieder gemerkt, wie töricht es ist, Menschen nach einer Sprache zu beurteilen

    • Dass der Aufstieg von Rails und der Niedergang von J2EE gleichzeitig stattfanden, war kein Zufall. Rails zeigte einfachen, meinungsstarken Backend-Code, und unter diesem Einfluss entstanden dann Java-Frameworks wie DropWizard, Javalin und Spring Boot
    • Mich würde interessieren, was der Tech-Stack dieses Seniors war
    • Ich würde am liebsten sogar den Mülleimer dieses Kollegen leeren. Gute Rails-Entwickler sind schwer zu finden. Ich habe auch RoR-Erfahrung und mag es immer noch
    • Wenn man gezielt Java-Entwickler sucht, kann es natürlich effizient sein, Rails-Lebensläufe auszusortieren
    • Die Kriterien, nach denen man Menschen bewertet, hängen letztlich von der kulturellen Passung zur Organisation und vom Stil der Zusammenarbeit ab. Eine perfekte Filtermethode gibt es nicht
  • Sprachen oder Bibliotheken sind letztlich Mittel zur Kommunikation sowohl mit Maschinen als auch mit Menschen. Mit Maschinen kommuniziert man über Bits und Spannungen, mit Menschen über Absichten und Konzepte. Wenn also eine Sprache oder Bibliothek dem Menschen eine klare und schnelle Ausdrucksform bietet, spielt es keine große Rolle, ob es sich um eine Sprache oder eine Bibliothek handelt. Rails oder Stanza — wenn es zum Zweck passt und vom Team leicht verstanden wird, ist das die richtige Antwort

  • Ich denke, „die Bibliothek ist die endgültige Sprache“. Ruby on Rails ist zum Beispiel eine hervorragende Sprache für Webservices auf Basis von Ruby. Ruby und Rails haben sich wechselseitig weiterentwickelt. Letztlich ist Programmierung ein fortlaufender Übersetzungsprozess von Sprache zu Sprache

    • C# und ASP.NET Core haben sich ähnlich gemeinsam entwickelt. Benutzerfreundliche Syntax und Optimierung auf Systemebene wurden gleichzeitig vorangetrieben
  • Die Aussage „Je mächtiger die Sprache, desto einfacher wird die Nutzung von Bibliotheken“ stimmt. Mit dem früheren Java wäre es schwierig gewesen, ein Framework wie Express zu bauen

    • Ich weiß nicht genau, was Express ist, aber ich denke, Java hat sich gerade wegen seiner guten Nutzbarkeit von Bibliotheken als Unternehmenssprache etabliert
    • Die minimal API von ASP.NET Core ist ein Beispiel dafür, Express fast eins zu eins umzusetzen. So etwas ist nur möglich, wenn sich Sprache und Framework gemeinsam weiterentwickeln
    • Auch in Java gibt es mit Javalin ein Framework ähnlich wie Express. Das Problem ist, dass die Community keine Einfachheit will
  • Wenn es um ein Web-Framework für C geht, dann gibt es doch PHP, oder? ;)

    • Das klingt eher wie ein Witz, der den Bibliotheksbegriff zu weit ausdehnt