Eines der Dinge, die Ruby zum Leuchten bringen, ist die Fähigkeit, domänenspezifische Sprachen besser zu erstellen
Obwohl man diese Bibliotheken in LISP über Makros duplizieren kann, finde ich Rubys Implementierung eleganter. Trotzdem denke ich, dass es Fälle gibt, in denen das Makro von LISP besser sein kann als das von Ruby, obwohl mir keines einfällt.
In welchem Bereich ist LISPs Makro besser als Rubys "Fähigkeit", DSL zu erstellen, wenn überhaupt?
aktualisieren
Ich habe das gefragt, weil moderne Programmiersprachen sich der LISP-Singularität nähern , wie
- C hat einen Präprozessor für die Makroerweiterung , ist jedoch sehr primitiv und fehleranfällig
- C # verfügt über Attribute, die jedoch schreibgeschützt sind und durch Reflektion verfügbar gemacht werden
- Python fügte einen Dekorator hinzu, der das Verhalten der Funktion (und der Klasse für Version 3.0) ändern kann, obwohl er sich recht begrenzt anfühlt.
- Ruby TMTOWTDI, das elegantes DSL macht, wenn Sorgfalt angewendet wird, aber auf Ruby-Weise.
Ich habe mich gefragt, ob das LISP-Makro nur auf Sonderfälle anwendbar ist und ob die anderen Programmiersprachenfunktionen leistungsfähig genug sind, um die Abstraktion zu erhöhen, um den heutigen Herausforderungen in der Softwareentwicklung gerecht zu werden.
Antworten:
Lies auf Lisp und entscheide dann selbst.
Meine Zusammenfassung ist, dass Ruby eine bessere Syntax bietet. Aber Lisp gewinnt zweifellos mit der Fähigkeit, neue Abstraktionen zu erschaffen und dann Abstraktion auf Abstraktion zu schichten. Aber Sie müssen Lisp in der Praxis sehen, um diesen Punkt zu verstehen. Daher das Buch empfehlen.
quelle
But Lisp wins, hands down, at the ability to create new abstractions, and then to layer abstraction on abstraction.
Jetzt weiß ich warum. . .Rubys Möglichkeiten für DSL-Authoring ändern nichts an der Art der Sprache. Rubys Metaprogrammierungsfunktionen sind von Natur aus an die Syntax und Semantik von Ruby gebunden, und alles, was Sie schreiben, muss in das Objektmodell von Ruby verschoben werden.
Vergleichen Sie dies mit Lisp (und Scheme, dessen Makrofunktionen sich unterscheiden ), in denen Makros auf das abstrakte Programm selbst angewendet werden. Da ein Lisp - Programm ist ein Lisp - Wert, ist ein Makro eine Funktionszuordnung eine im wesentlichen beliebige Syntax zum anderen.
Tatsächlich fühlt sich ein Ruby-DSL immer noch wie ein Ruby an, aber ein Lisp-DSL muss sich nicht wie ein Lisp anfühlen.
quelle
Rubys DSLs sind überhaupt keine DSLs, und ich hasse es, sie zu verwenden, weil in ihrer Dokumentation alles darüber steht, wie sie wirklich funktionieren. Nehmen wir zum Beispiel ActiveRecord. Damit können Sie Assoziationen zwischen Modellen "deklarieren":
Aber die Deklarativität dieses "DSL" (wie die Deklarativität von Rubys
class
Syntax selbst) ist eine schreckliche Lüge, die jeder entlarven kann, der versteht, wie Rubys "DSLs" tatsächlich funktionieren:(Versuchen Sie einfach, etwas in der Nähe des Körpers einer Lisp-
defclass
Form zu tun !)Sobald Sie Code wie den oben genannten in Ihrer Codebasis haben, muss jeder Entwickler im Projekt vollständig verstehen, wie Ruby-DSLs tatsächlich funktionieren (nicht nur die Illusion, die sie erstellen), bevor er den Code verwalten kann. Die verfügbare Dokumentation ist völlig nutzlos, da sie nur die idiomatische Verwendung dokumentiert , die die deklarative Illusion bewahrt.
RSpec ist noch schlimmer als die oben genannten, da es bizarre Edge-Cases gibt, die ein umfangreiches Reverse-Engineering zum Debuggen erfordern. (Ich habe einen ganzen Tag lang versucht, herauszufinden, warum einer meiner Testfälle übersprungen wurde. Es stellte sich heraus, dass RSpec alle Testfälle mit Kontexten nach Testfällen ohne Kontext ausführt , unabhängig von der Reihenfolge, in der sie in der Quelle angezeigt werden , weil die
context
Methode Ihren Block in eine andere Datenstruktur legt als normalerweise.)Lisp-DSLs werden von Makros implementiert, die kleine Compiler sind. Die DSLs, die Sie auf diese Weise erstellen können, sind kein Missbrauch der vorhandenen Syntax von Lisp. Sie sind echte Minisprachen, die nahtlos geschrieben werden können, weil sie ihre eigene Grammatik haben können. Zum Beispiel ist Lisps
LOOP
Makro viel leistungsfähiger als Rubyseach
Methode.(Ich weiß, dass Sie bereits eine Antwort akzeptiert haben, aber nicht jeder, der dies liest, wird die Gesamtheit von On Lisp lesen wollen .)
quelle