Clojure gegen andere Lisps [geschlossen]

93

Die Absicht meiner Frage ist nicht , einen Flammenkrieg zu beginnen, sondern zu bestimmen, unter welchen Umständen jede Sprache "das beste Werkzeug für den Job" ist.

Ich habe mehrere Bücher über Clojure gelesen ( Programmieren von Clojure , Praktisches Clojure , Die Freude an Clojure und die Manning Early Access-Ausgabe von Clojure in Aktion ), und ich denke, es ist eine fantastische Sprache. Ich lese gerade Let Over Lambda, das sich hauptsächlich mit Common Lisp-Makros befasst und auch eine sehr interessante Sprache ist.

Ich bin kein Lisp-Experte (eher ein Neuling), aber diese Sprachfamilie fasziniert mich ebenso wie die funktionale Programmierung im Allgemeinen.

Vorteile von Clojure (und Nachteile von "anderen"):

  • Läuft auf der JVM.

    • Die JVM ist eine sehr stabile, leistungsstarke Sprachumgebung, die Suns Traum vom "Einmal schreiben, [fast] überall ausführen" ziemlich gut erfüllt. Ich kann Code auf mein Macbook Pro schreiben, ihn in eine ausführbare JAR-Datei kompilieren und ihn dann unter Linux und Microsoft Windows mit wenig zusätzlichen Tests ausführen.

    • Die (Hotspot- und andere) JVM unterstützt eine qualitativ hochwertige Speicherbereinigung und eine sehr performante Just-in-Time-Kompilierung und -Optimierung. Wo ich vor ein paar Jahren alles geschrieben habe, was in C schnell laufen musste, zögere ich jetzt nicht, dies in Java zu tun.

    • Standardmodell, einfaches Multithreading-Modell. Hat Common Lisp ein Standard-Multithreading-Paket?

    • Bricht die Monotonie all dieser Klammern mit [], auf {}, und #{}obwohl Common Lisp-Experten mir wahrscheinlich sagen werden, dass Sie diese mit Lesermakros zu CL hinzufügen können.

Nachteile von Clojure :

  • Läuft auf der JVM.
    • Keine Schwanzrekursion oder Fortsetzung. Unterstützt Common Lisp Fortsetzungen? Ich glaube, das Programm erfordert Unterstützung für beide.

Vorteile anderer (insbesondere Common Lisp) (und Nachteile von Clojure):

  • Benutzerdefinierte Lesermakros.

  • Weitere Vorteile?

Gedanken? Andere Unterschiede?

Ralph
quelle
15
persönlich mag ich eine Art von Klammern;) sieht aus wie "sauberer" Code
Moe
3
Nach dem, was ich auf Ihrer Vorteilsliste gelesen habe, könnte Ihnen Erlang vielleicht auch gefallen. Www.erlang.org
Peer Stritzinger
4
Clojure unterstützt die explizite Schwanzrekursion über das Sonderformular "wiederkehren". Auf diese Weise können Sie alle Vorteile der Schwanzrekursion nutzen, sofern Sie ausdrücklich danach fragen (die einzige Ausnahme besteht darin, dass derzeit keine gegenseitigen Schwanzrekursionen zwischen mehreren Funktionen unterstützt werden).
Mikera
1
Clojure unterstützt auch Fortsetzungen, zumindest im Sinne von "Continuation Passing Style". Sie haben Recht, dass es keine erstklassigen Fortsetzungen gibt. Siehe stackoverflow.com/questions/1173133/continuations-in-clojure
mikera
@mikera: Schwanzrekursion für eine Funktion. Zwei Funktionen, die sich gegenseitig aufrufen, müssen mit "Trampolin" erledigt werden, was irgendwie klobig ist (aber auf seine Weise elegant :-)).
Ralph

Antworten:

52

Meine persönliche Liste der Gründe, warum ich Clojure anderen Lisps vorziehe (ps Ich finde immer noch, dass alle Lisps großartig sind!):

  • Läuft auf der JVM - erhält daher automatischen Zugriff auf das fantastische Engineering in der JVM selbst (erweiterte Garbage Collection-Algorithmen, HotSpot JIT-Optimierung usw.)

  • Sehr gute Java-Interoperabilität - bietet Kompatibilität mit der Vielzahl von Bibliotheken im Java / JVM-Sprachökosystem. Ich habe Clojure als "Klebesprache" verwendet, um verschiedene Java-Bibliotheken mit guter Wirkung zu verbinden. Da ich auch viel Java-Code entwickle, ist es für mich hilfreich, dass Clojure gut in Java-Tools integriert ist (z. B. verwende ich Maven, Eclipse mit Plugin gegen den Uhrzeigersinn für meine Clojure-Entwicklung).

  • Schöne Syntax für Vektoren [1 2 3], Karten {:bob 10, :jane 15}und Mengen #{"a" "b" "c"}- ich halte diese ziemlich wichtigen Werkzeuge für die moderne Programmierung (zusätzlich zu Listen natürlich!).

  • Ich persönlich mag die Verwendung von eckigen Klammern zum Binden von Formularen: zB (defn foo [a b] (+ a b))- Ich denke, das macht das Lesen von Code etwas klarer.

  • Der Schwerpunkt liegt auf einer verzögerten, funktionalen Programmierung mit dauerhaften, unveränderlichen Datenstrukturen. Insbesondere die gesamte Clojure-Kernbibliothek unterstützt dies standardmäßig

  • Hervorragende STM-Implementierung für Multi-Core-Parallelität. Ich glaube, Clojure hat momentan die beste Parallelitätsgeschichte aller Sprachen (siehe dieses Video für weitere Informationen von Rich Hickey selbst ).

  • Es ist ein Lisp-1 (wie Schema), das ich persönlich bevorzuge (ich denke, in einer funktionalen Sprache ist es sinnvoll, Funktionen und Daten im selben Namespace zu halten).

mikera
quelle
2
+1 für das STM. Es allein reicht aus, um die Verwendung von Clojure zu rechtfertigen.
André Caron
2
Sie können STM weiterhin mit der Bibliothek CL-STM erhalten.
Mike Manilone
2
@ AndréCaron nur wenn du es brauchst.
Rechtsfalte
Wenn Sie eine einfache Webanwendung schreiben und sie beispielsweise auf einem billigen Host für 5 US-Dollar pro Monat hosten möchten, ist dies mit Clojure aufgrund von JVM offensichtlich nicht möglich, richtig?
Hexatonic
@Hexatonic Ich bin nicht sehr erfahren, aber es ist schwer zu glauben, dass eine heutzutage verwendete Maschine keine JVM haben würde.
MasterMastic
25

Beachten Sie, dass Clojure eine Sprache und eine Implementierung ist (normalerweise in der JVM). Common Lisp ist eine Sprache mit mehr als zehn verschiedenen Implementierungen. Wir haben hier also eine Kategorie-Nichtübereinstimmung. Sie können beispielsweise Clojure mit SBCL vergleichen.

Allgemein:

  • Eine Version von Common Lisp läuft auf der JVM: ABCL

  • Die meisten anderen Common Lisp-Implementierungen tun dies nicht

  • Die meisten CL-Implementierungen verfügen über Multitasking-Funktionen. Eine Bibliothek bietet eine gemeinsame Schnittstelle

  • Common Lisp hat eine Syntax für Arrays. Die Syntax für andere Datentypen kann vom Benutzer geschrieben werden und wird von verschiedenen Bibliotheken bereitgestellt.

  • Common Lisp unterstützt weder Tail Call-Optimierung noch Fortsetzungen. Implementierungen bieten Gesamtbetriebskosten und Bibliotheken bieten eine Form von Fortsetzung.

Rainer Joswig
quelle
24

Ein wichtiger Unterschied zwischen Clojure und Common Lisp besteht darin, dass Clojure die funktionale Programmierung genauer beschreibt. Clojures Philosophie, Redewendungen und bis zu einem gewissen Grad Sprache / Bibliotheken ermutigen stark und bestehen manchmal darauf, dass Sie auf funktionale Weise programmieren (keine Nebenwirkungen, kein veränderlicher Zustand).

Common Lisp unterstützt definitiv die funktionale Programmierung, ermöglicht aber auch veränderbare Zustands- und Imperativprogrammierung.

Natürlich bietet die funktionale Programmierung im Bereich der Parallelität und auf andere Weise eine Reihe von Vorteilen. Wenn alles andere gleich ist, ist es auch gut, die Wahl zu haben, welchen Ansatz Sie für jede Situation verwenden möchten. Clojure verbietet die imperative Programmierung nicht vollständig, ist diesem Stil jedoch weniger entgegenkommend als Common Lisp.

Charlie Flowers
quelle
3
@Charlie Flowers: Ich glaube, dass es in Common Lisp möglich ist, in einem "rein funktionalen" Stil zu programmieren (Unterstützung für dauerhafte Datenstrukturen usw.), aber Disziplin erfordert. Richtig?
Ralph
2
Nur eine Klarstellung zu "keine Nebenwirkungen, kein veränderlicher Zustand" - Clojure hat zwar einen veränderlichen Zustand (Refs, Atome, Agenten usw. sind alle veränderlich), erfordert jedoch einen kontrollierten Zugriff (dh über die STM-Mechanismen und die damit verbundenen Transaktionen) Update Semantik)
Mikera
5
@mikera: mit der Ausnahme, dass Clojure auf die Verwendung von Java-Bibliotheken angewiesen ist, um verwendet werden zu können, und dass all diese Bibliotheken einen imperativen Stil erfordern und voller Nebenwirkungen sind. Ich habe festgestellt, dass die Bindungen mit Java ein vergiftetes Geschenk sind ...
André Caron
1
@Andre - sicher, wenn Sie sich für die Verwendung einer Bibliothek entscheiden, die einen veränderlichen Status und eine imperative Semantik erfordert, müssen Sie dies verwalten. Dies unterscheidet sich nicht davon, wenn Sie von einer anderen Sprache aus auf eine solche Bibliothek zugegriffen haben. Sie haben jedoch zwei gute Möglichkeiten: a) Verwenden Sie solche Bibliotheken nicht - Sie können perfekt guten Code in reinem Clojure schreiben oder b) die Komplexität der Schnittstelle zu diesen Bibliotheken in eine schöne funktionale Oberfläche im Clojure-Stil einbinden, die normalerweise einfach ist Makros oder Agenten usw. Insgesamt habe ich festgestellt, dass die Möglichkeit, Java-Bibliotheken zu nutzen, einen viel größeren Vorteil hat als das Problem.
Mikera
4
@mikera: Die Bibliotheken haben einen Vorteil. Ich möchte nur darauf hinweisen, dass die Verwendung von Java-Bibliotheken (dies ist eines der Hauptziele von Rich Hickey für die Sprache) wirklich gegen den Aspekt "funktionaler als andere Lisps" von Clojure verstößt. Mein Kommentar sollte bedeuten: "Wenn Sie diese Bibliotheken nicht umschreiben / verpacken, erhalten Sie zwingend aussehenden Code und profitieren nicht von Clojures schöneren Teilen."
André Caron
10

Hier ist ein gutes Video mit einem Vergleich von Scheme (meistens Racket) und Clojure .

Um fair zu sein, hat Racket auch Syntaxzucker (zusätzliches Reader-Zeug) für Datentypen (#hash, #, eckige Klammern usw.).

Außerdem besteht Clojures einzige Möglichkeit, einen ordnungsgemäßen Tail-Aufruf zu tätigen, in der Verwendung recur. Dies ist der Nachteil beim Kompilieren in JVM.

Beachten Sie, dass dies recurdas einzige nicht stapelintensive Schleifenkonstrukt in Clojure ist. Es gibt keine Tail-Call-Optimierung und die Verwendung von Self-Calls zum Schleifen unbekannter Grenzen wird nicht empfohlen. recurist funktionsfähig und seine Verwendung in der Endposition wird vom Compiler überprüft. ( Sonderformulare ).

Daniil
quelle
Link ist tot, denke ich.
Nawfal
1
@nawfal Ich glaube, ich habe es behoben
Daniil
6
Link ist tot (wieder?)
Konto
1
Das Video zu diesem Link finden Sie hier: vimeo.com/22675078 .
GDP2
Es gibt auch trampolinefür Tail Calls.
HappyFace