Die Programmiersprache Racket
(racket-lang.org)- Racket ist eine ausgereifte Sprache, bei der sprachorientierte Programmierung im Mittelpunkt steht und die allgemeine Anwendungsentwicklung und die Entwicklung neuer Sprachen im selben Ökosystem zusammenführt
- Im Kern stehen Makros und
#lang; damit lassen sich neue Syntax, domänenspezifische Sprachen und bestehende Oberflächensyntax wie Bibliotheken erstellen und auf Modulebene verwenden - Standardbibliotheken, die von Webservern, Datenbanken sowie Mathematik und Statistik bis zu GUI und wissenschaftlichen Simulationen reichen, zusammen mit Tausenden Paketen erweitern den Umfang der allgemeinen Entwicklung
- Typed Racket, Verträge, Objektsystem und die DrRacket-IDE werden gemeinsam bereitgestellt, sodass sich funktionaler Code, objektorientierte Komponenten und schrittweise Typisierung je nach Bedarf kombinieren lassen
- Racket ist nicht einfach nur eine Lisp-Familien-Sprache, sondern eher eine Entwicklungsumgebung, die für jeden Problembereich passende Sprachen erstellen und sie mit Ausführung, Bearbeitung und Tool-Unterstützung verbinden will
Racket für sprachorientierte Programmierung
- Racket ist eine Programmiersprache, die zugleich mit „Racket, the Programming Language“ und „Racket, the Language-Oriented Programming Language“ auftritt
- Racket version 9.2 ist verfügbar
- Es ist ein ausgereiftes Produkt, das seit seinen Anfängen plattformübergreifende grafische Programmierung unter Windows, macOS und Linux unterstützt
- Die grundlegenden Entwicklungsfunktionen umfassen Paketverwaltung, GUI, eigenständige ausführbare Binärdateien und externe Schnittstellen
Umfang der allgemeinen Anwendungsentwicklung
- Racket verfügt über ein Bibliothekspaket, das von Webserver-Anwendungen bis zu Mathematik und Software für wissenschaftliche Simulationen reicht
- Zu den repräsentativen Dokumenten und Bibliotheksbereichen gehören:
- Eine plattformübergreifende GUI-Toolbox und der Webserver sind Teil des Standard-Ökosystems
- Tausende zusätzliche Pakete lassen sich mit einem einzigen Befehl installieren
- Beispiele sind 3D graphics, Bluetooth socket connector, color maps, data structures, educational software, games, quantum-random number generator, scientific simulations und web script testing
- Das Beispiel
#lang racket/guiimplementiert in einem GUI-Dialekt ein kleines Zahlratespiel und nutzt dabei mehrere Sprachfunktionen gemeinsam
Mit Makros erweiterte Sprache
- Racket-Programmierer können mit Makros eigene Schleifen und neue Syntax definieren
- Neue Syntax wird ähnlich wie Prozeduren, Methoden und Klassen hinzugefügt; dazu genügt es, Regeln zu erstellen, die benutzerdefinierte Syntax in Racket-Ausdrücke oder Definitionen umschreiben
- Kleine Makros helfen dabei, wiederholten Code zu vermeiden, der sich mit anderen Mitteln nur schwer behandeln lässt
- Es lässt sich eine
time-it-Syntax definieren, die die Laufzeit einer Aufgabe misst - Wiederholte Verwendung von
lambdalässt sich vermeiden - Makros werden wie normale Funktionen aus Modulen exportiert
- Es lässt sich eine
- Das vollständige Makrosystem kann auch Strukturen aufbauen, in denen mehrere Makros zusammenarbeiten
- Racket ist eine funktionale Sprache, bietet aber von Anfang an eine Untersprache für classes and objects, mixins and traits
- Das an Java angelehnte Klassensystem ist als makrobasierte Bibliothek implementiert und funktioniert ohne separate Unterstützung durch die Kernsprache
#lang und domänenspezifische Sprachen
- Racket versteht sich als Sprache zum Erstellen von Sprachen, damit Programmierer jedes Modul in einer passenden Sprache schreiben können
- Das Beispiel
#lang typed/racketverwendet den union type vonStringundNumber, occurrence typing und Listenfilterung - Das Beispiel
#lang scribble/basebehandelt eine Dokumentensprache, die PDF- oder HTML-Dokumente erzeugt - Das Beispiel
#lang datalogverwendet Datalog-Syntax zum Definieren und Abfragen vonparent- undancestor-Beziehungen - Neue Sprachen können in einem IDE-Fenster erstellt und die Module dieser Sprache in einem anderen IDE-Fenster ausgeführt werden, ohne Konfiguration, Projektdateien oder externe Tools
- Racket-Nutzer verwenden meist Klammer-Syntax, können aber auch bestehende Oberflächensyntax erstellen, die wie bei Datalog Kommas und geschweifte Klammern benötigt
- Mit parsing packages lässt sich beliebige Grammatik auf eine klammerbasierte Sprache abbilden und mit dem Racket-Makrosystem in normales Racket kompilieren
DrRacket und das Entwicklungsökosystem
- Racket bietet mit DrRacket eine eigene IDE, die beim Überfahren eines Bezeichners mit der Maus einen Pfeil zum Ort seiner Definition zeichnet
- Auch bei der Verwendung alternativer Sprachen wie Typed Racket lässt sich die Bearbeitungsunterstützung von DrRacket nutzen
- Racket-Makros zeichnen ausreichend Quellinformationen auf und geben sie weiter, selbst bei komplexen Makros oder Makros, die neue Sprachen erzeugen, sodass DrRacket so arbeiten kann, als verstünde es die neuen Sprachfunktionen
- Zu den wichtigsten Entwicklungswerkzeugen gehören:
- Zu den Ressourcen des Ökosystems gehören Downloads, Quellcode, Fehlerberichte, nightly snapshot builds und ein Paket-Repository
- Als Lernmaterial und Dokumentation stehen Quick Introduction, The Racket Guide, The Racket Reference und All Documentation zur Verfügung
- Als Community-Kanäle gibt es Discourse, Discord, Slack, Reddit, Mailinglisten, Mastodon, Twitter, Blog, Wiki und YouTube; außerdem stehen Dokumente zu Team und Contributing bereit
1 Kommentare
Hacker-News-Kommentare
Schön, Racket auf der Titelseite zu sehen. Seit 1982 habe ich für Forschungsprogrammierung hauptsächlich Common Lisp verwendet, aber in letzter Zeit greife ich öfter zu Racket.
Es gibt auch Dinge an Racket, die mir nicht gefallen – im Grunde fast alles außer dem Compiler, dem Paketverwaltungssystem, der GUI-IDE, den Emacs-Bindings und der Tatsache, dass es eine Sprache ist, in der das Schreiben Spaß macht.
Am Ökosystem rund um Programmiersprachenforschung habe ich wenig Interesse; vermutlich ist das der Teil, der den Informatikprofessoren, die das Projekt leiten, am wichtigsten ist. Trotzdem wünsche ich ihnen Erfolg.
Deshalb habe ich auch das Gefühl, beim Racket-Projekt ein Trittbrettfahrer zu sein. Ich genieße nur die kleinen Teile, die ich mag, ignoriere den Rest und trage kaum etwas bei. Eine Ausnahme könnte höchstens das kleine Racket-Buch sein, das ich geschrieben habe.
Diese Funktionen sind wirklich nützlich und wichtig. Ich mag Lisp, aber im Beruf nutze ich eine Sprache nur, wenn sie das beste Werkzeug für die Aufgabe ist. Dank solcher Funktionen war Racket das einzige Lisp, dessen praktischen Einsatz ich tatsächlich rechtfertigen konnte.
Wegen der Community, der Tools und der Lernmaterialien ist Racket für mich persönlich eine Sprache, die man leicht weiterempfehlen kann. Ich habe auch viel CL und Clojure verwendet und mag manches daran, aber beide haben jeweils große Nachteile, weshalb ich sie anderen nicht empfehle.
Auch ich kann mit dem Forschungsaspekt der Sprache oder den
lang-Funktionen nicht viel anfangen, und HtDP mag ich ebenfalls eher nicht. Aber das sind für mich nur Projekte, die mich nicht interessieren und die in einer Sprache gebaut wurden, die ich mag – keine Nachteile der Sprache selbst. In der Praxis stößt man nämlich kaum darauf.Das kann man durchaus als großen Beitrag ansehen :)
Die Sprache selbst hat Metaprogramming-Funktionen, aber moderne Sprachen haben alle Metaprogramming.
Meine Erfahrung in der Community war überwiegend, dass dort Leute über reale Probleme sprechen.
Da Racket in der Programmiersprachenforschung und auch in anderen Forschungsbereichen verwendet wird, wird es in entsprechenden Papers und Konferenzvorträgen erwähnt, dominiert die Diskussion aber nicht.
Beispiel: https://racket.discourse.group/t/levin-tree-search-with-cont...
Clojure hat allerdings eine größere und robustere Community. Dafür nutzt es die JVM, was die Einrichtung etwas umständlicher macht und auch ein paar subtile Dinge mit sich bringt, auf die man achten muss.
Racket ist eine sehr praktische Sprache. Wenn es wie eine akademische Marotte wirkt, lohnt sich ein Blick darauf, was Bogdan Popa mit Racket macht: https://defn.io/
Persönlich verwende ich Racket, wenn ich eine Binärdatei mit nativer GUI brauche. Auch zum Parsen von Dingen wie JSON, XML oder textbasierten Dateiformaten eignet es sich ziemlich gut.
Das begleitende Buch How to Design Programs, https://htdp.org/2023-8-14/Book/index.html, ist ebenfalls gut. Es ist nicht genau ein Buch, das Racket lehrt, sondern verwendet einige in Racket implementierte Lehrsprachen, enthält aber Ideen, über die es sich gelegentlich lohnt nachzudenken.
Das Makrosystem kann für Leute, die etwa aus CL kommen, seltsam wirken, aber nachdem ich mich daran gewöhnt hatte, fiel es mir damit relativ leicht, beim Metaprogramming den Verstand zu behalten.
Noch ein paar nützliche Ressourcen:
https://www.greghendershott.com/fear-of-macros/
https://beautifulracket.com/
Ich mag die Sprache Racket wirklich sehr, aber den erzwungenen Workflow finde ich schwer zu akzeptieren. Wenn ich in Python programmiere, schreibe ich den Code im Editor und führe ihn in der Shell aus.
Bei Racket klappt das nicht so gut, weil die Startzeit viel zu lang ist. Stattdessen heißt es, man solle mit einer langlebigen virtuellen Maschine und einer REPL interagieren.
Dann startet der Code, an dem man arbeitet, aber nicht in einem sauberen Zustand, sondern in dem Zustand, den die virtuelle Maschine in diesem Moment hat. Für Dinge wie Jupyter Notebooks ist das ein großartiger Ablauf, aber für große Programme halte ich ihn für weniger passend.
Statt
racketdas#langracket/basezu verwenden, macht ebenfalls einen großen Unterschied. Details stehen unter https://docs.racket-lang.org/style/Language_and_Performance.....Dass man nicht in einem „sauberen Zustand“ startet, klingt für mich eher nach einer Common-Lisp-artigen REPL als nach Racket. In Racket muss man normalerweise Racket neu starten, wenn man eine Datei oder ein Modul erneut lädt, und bekommt dadurch eine frische Umgebung. Viele beschweren sich darüber, aber ich bevorzuge Rackets Ansatz mit sauberem Zustand gegenüber CL.
https://docs.racket-lang.org/drracket/drracket-files.html#(p...
Wahrscheinlich kann man auch den Wiederherstellungsvorschlag ablehnen.
„Wenn DrRacket zum ersten Mal startet, prüft es, ob noch Backup-Dateien vorhanden sind, und schlägt, falls ja, vor, die Backup-Dateien wiederherzustellen.“
Als ich an der University of British Columbia studierte, wurde Racket im Einführungskurs für Informatik gelehrt. Ich hielt es für eine ausgezeichnete Sprache, und weil selbst Studierende mit vorheriger Programmiererfahrung fast nie Lisp gemacht hatten, brachte es alle auf dieselbe Ausgangsbasis.
Auch die Bibliotheken, mit denen man leicht einfache Spiele oder Visualisierungen erstellen konnte, fand ich beeindruckend.
Als ich Tutor war, konnten viele Studierende im zweiten Jahr noch nicht einmal for-Schleifen schreiben und lagen bei grundlegenden Algorithmen weit zurück.
Eine tiefere Wertschätzung für funktionale Sprachen entwickelte ich erst nach einem Kurs zur Berechnungstheorie im vierten Jahr.
Ich verstehe nicht, wie man all diese „Sprachen“ von Racket in einer Anwendung zusammenführen soll. Ich sehe Sprachen wie
typed/racket,racket/gui,scribble/base, aber ich habe keine Vorstellung davon, wie man eine GUI-Anwendung mit typisiertem Code erstellt und dabei auch PDFs generiert.Ich habe Racket-Tutorials mehrfach durchgearbeitet, bin aber immer noch verwirrt, wie man diese scheinbar unabhängigen „Sprachen“ miteinander verbindet.
Persönlich fühlt es sich für mich so an, als würde jedes Kapitel des Tutorials nur eine jeweils nicht zusammenhängende „Sprache“ erklären und nie zeigen, wie sie zusammenarbeiten. Ein Kapitel behandelt einen Webserver, aber nicht das Klassensystem; ein anderes Kapitel behandelt eine andere „Sprache“, die Klassen unterstützt, schreibt darin aber keinen Webserver.
#lang-Zeile als eine Art Compiler-Direktive vorstellen, die für die jeweilige Datei gilt. In Wirklichkeit steckt viel mehr dahinter, aber als Ausgangspunkt ist das in Ordnung. Wenn du deiner Anwendung Typen hinzufügen willst, ist es eine gute Strategie, das Datei für Datei zu tun.Neben der
#lang-Zeile kannst du mitrequireBibliotheken importieren, also kannst du GUI-Code und Webserver-Code auch in dieselbe Datei packen. Auch#langist nicht strikt darauf beschränkt, nur eine einzige Sprache auf einmal zu verwenden; wenn es keine Konflikte gibt, kann man in dieser Zeile mehr hinzufügen."racket"schreiben. Wenn dir Typen wichtig sind, könnte ein großer Teil davon"typed/racket"sein.Es stimmt, dass alle Sprachen eine gemeinsame Basis teilen und bis zu einem gewissen Grad interoperabel sind, aber es ist keineswegs wahrscheinlich, dass man ein Programm in fünf gleich große Teile aufteilt und für jeden eine andere Sprache verwendet. Die Dokumentation wirst du vermutlich in Scribble schreiben.
Wenn man unterschiedliche Sprachen verwendet, kann man grundsätzlich unterschiedliche Programmiermodelle haben; das ist auch der Hintergrund, der Entwicklungen wie Typed Racket möglich gemacht hat. Aber es sollte kein Hindernis für den Einstieg sein.
Kurz gesagt: Verwende einfach Racket. Wenn du wirklich das Gefühl hast, eine andere Funktion oder einen anderen Programmierstil zu brauchen, kannst du dann nachsehen, ob es bereits eine passende Sprache dafür gibt. Natürlich ist das alles nur meine Meinung.
Diese Website, Hacker News, wurde in Arc geschrieben und läuft auf Racket: https://en.wikipedia.org/wiki/Arc_(programming_language)
Das größte Problem von Racket ist nicht die Sprache oder das Ökosystem: https://news.ycombinator.com/item?id=27531508
Selbst wenn man diesen Link vollständig für bare Münze nimmt und annimmt, dass Felleisen in bestimmten persönlichen Interaktionen auf Torvalds-Art gemein ist, haben seine Arbeiten, darunter How To Design Programs, mein Leben und das Leben anderer sehr positiv beeinflusst. Deshalb würde ich den Leuten nicht davon abraten, sie zu nutzen.
In der Community gibt es auch „seltsame Nerds“ mit starken Meinungen, deren Präsenz dadurch stärker auffällt und die deshalb nerviger wirken können. Aber wie in vielen sozialen Räumen, in denen kein Geld die Ordnung zusammenhält, ist das eben so.
Racket ist meine Lieblingssprache. Sie ist schnell und praktisch, hat eine solide Grundlage und auch ein sehr gutes Concurrency-Modell. Es basiert auf Konzepten, die aus Concurrent ML übernommen und erweitert wurden.
Das Dokumentationssystem ist ebenfalls hervorragend und in das Paket-Ökosystem integriert, sodass die meisten Pakete hochwertige Dokumentation mit Querverweisen haben. Die Abwärtskompatibilität ist auch ausgezeichnet; meiner Ansicht nach ist sie deutlich besser als bei Python, das ich derzeit in meinem Hauptjob verwende.
Daher habe ich bei Leuten, die sagen, Racket sei zu akademisch oder nicht praktisch genug, das Gefühl, dass sie sich entweder nicht tief genug damit befasst haben oder früher als Studierende nur mit den Lehrsprachen in Berührung gekommen sind.
Natürlich ist es nicht perfekt. Die Community ist klein, der grundlegende Speicherverbrauch der Runtime ist hoch, und für parallele Verarbeitung muss man pro System-Thread jeweils eine Racket-VM starten, unter anderem. Trotzdem werden sich solche Dinge mit der Zeit verbessern.
Dinge, die ich in den letzten Jahren mit Racket gebaut habe: eine E-Commerce-Site[1], eine native macOS/iOS-Erinnerungs-App im App Store[2, 3, 4], einen plattformübergreifenden Desktop-Client für Apache Kafka[5, 6, 7], ein
#langfür Lua[8]. Daneben gibt es noch Verschiedenes[9][10][11]. Ich halte das für ziemlich praktische Dinge.[1]: https://defn.io/2019/08/20/racket-ecommerce/
[2]: https://defn.io/2020/01/02/ann-remember/
[3]: https://defn.io/2024/04/09/ann-remember-for-ios/
[4]: https://github.com/bogdanp/remember
[5]: https://defn.io/2022/11/20/ann-franz/
[6]: https://defn.io/2023/10/15/ann-franz-for-windows/
[7]: https://defn.io/2023/08/10/ann-franz-source-available/
[8]: https://defn.io/2022/11/12/ann-racket-lua/
[9]: https://docs.racket-lang.org/http-easy/index.html
[10]: https://docs.racket-lang.org/deta/index.html
[11]: https://docs.racket-lang.org/gui-easy/index.html
Auch im Community-Forum ist er sehr aktiv und gibt wirklich viele hilfreiche Antworten.
Ich wollte ihn unbedingt erwähnen, weil ich ihn für einen heimlichen Helden dieser Sprache halte. Man kann sagen, dass deine Bibliotheken Code antreiben, der ahnungslosen Nutzern das Leben deutlich leichter macht :)
https://docs.racket-lang.org/http-easy/index.html
https://docs.racket-lang.org/gui-easy/index.html
https://racket.discourse.group
Das könnte an den Bereichen liegen, in denen Python heute hauptsächlich eingesetzt wird. Der Numeric/Numpy-Übergang um 2000 war völlig anders.
Alle paar Jahre etwas kaputtzumachen mag für Unicorn-Startups oder Unternehmen in Ordnung sein, die sich schnell bewegen und im wörtlichen Sinne Dinge kaputtmachen. Aber es gibt viele wertvolle Programme für Menschen und Organisationen, die es sich nicht leisten können, ausgereifte Algorithmen alle paar Jahre neu zu schreiben, oder das nicht als Priorität ansehen.
Ich nutze Racket gelegentlich und mag es. Allerdings ist mir klar geworden, dass einige Lisps, insbesondere Common Lisp und wahrscheinlich auch Guile, stärker unterschätzt werden, als man denkt.
Ich würde gern Leute fragen, die sich besser auskennen: Welche Racket-Features wirken anfangs nicht praktisch, relevant oder nützlich, erweisen sich beim Ausprobieren aber als überraschend hilfreich fürs Programmieren?
Vor etwa 20 Jahren habe ich an einer kommerziellen E-Mail-Sicherheitssoftware gearbeitet, die MzScheme als Basissprache nutzte, noch bevor daraus PLT Scheme wurde. Der Code war plattformübergreifend und lief auf Solaris, Linux und HP-UX; der betriebssystemspezifische Code umfasste etwa 1.000 Zeilen C.
Die Filterregeln wurden in Scheme selbst kompiliert. Einschließlich der webbasierten UI umfasste der gesamte Code etwa 30.000 Zeilen, und es gab nur 5 bis 6 Entwickler.
Später, nach meiner Auswanderung, kam ich zu einem Unternehmen mit einem ähnlichen, aber funktionsärmeren Produkt; dieses bestand aus Hunderttausenden Zeilen C++ und hatte auch mehr Entwickler.