it-swarm.com.de

Clojure gegen andere Lisps

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 ( Programming Clojure , Practical Clojure , The Joy of Clojure und das Manning Early gelesen Greifen Sie auf die Ausgabe von Clojure in Action ) zu, 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 das funktionale Programmieren 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 von "Einmal schreiben, fast überall ausführen" ziemlich gut erfüllt. Ich kann Code auf meinem Macbook Pro schreiben, ihn in eine ausführbare JAR-Datei kompilieren und ihn dann mit wenigen zusätzlichen Tests unter Linux und Microsoft Windows ausführen.

    • Die (Hotspot- und andere) JVM unterstützt eine qualitativ hochwertige Garbage Collection 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.

    • Standard, einfaches Multithreading-Modell. Verfügt Common LISP über ein Standardpaket für Multithreading?

    • Bricht die Monotonie all dieser Klammern mit [], {}, und #{}, obwohl Common LISP-Experten mir wahrscheinlich sagen werden, dass Sie diese mit Reader-Makros 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):

  • Benutzerdefinierbare Reader-Makros.

  • Weitere Vorteile?

Gedanken? Andere Unterschiede?

87
Ralph

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

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

  • Sehr gute Java Interoperabilität - Bietet Kompatibilität mit den zahlreichen Bibliotheken im Java/JVM-Sprachumfeld. Ich habe Clojure als "Klebesprache" verwendet, um verschiedene Java - Bibliotheken effektiv zu verbinden. Da ich auch viel Java Code entwickle, ist es für mich hilfreich, dass sich Clojure gut in Java Tools integrieren lässt (z. B. verwende ich Maven, Eclipse mit Counterclockwise Plugin für meine Clojure-Entwicklung).

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

  • Ich persönlich mag die Verwendung von eckigen Klammern für Bindungsformen: z.B. (defn foo [a b] (+ a b)) - Ich denke, es macht den Code ein bisschen klarer zu lesen.

  • Der Schwerpunkt liegt auf einer faulen, funktionalen Programmierung mit beständigen, unveränderlichen Datenstrukturen - insbesondere die gesamte Clojure-Kernbibliothek ist standardmäßig darauf ausgelegt, dies zu unterstützen

  • Hervorragende STM-Implementierung für Mehrkern-Parallelität. Ich glaube, Clojure hat derzeit die beste Nebenläufigkeitsgeschichte aller Sprachen (siehe dieses Video für weitere Erläuterungen von Rich Hickey selbst )

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

47
mikera

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 Sie nachdrücklich und bestehen manchmal darauf, dass Sie auf funktionale Weise programmieren (keine Nebenwirkungen, kein veränderlicher Zustand).

Common LISP unterstützt auf jeden Fall die funktionale Programmierung, ermöglicht jedoch auch die Änderung des Status und die zwingende Programmierung.

Natürlich bietet die funktionale Programmierung eine Reihe von Vorteilen, unter anderem im Bereich der Parallelität. 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 das imperative Programmieren nicht vollständig, aber es ist diesem Stil weniger entgegenkommend als Common LISP.

24
Charlie Flowers

Denken Sie daran, 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önnten beispielsweise Clojure mit SBCL vergleichen.

Allgemein:

  • auf der JVM: ABCL wird eine Version von Common LISP ausgeführt

  • die meisten anderen gängigen 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. 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 TCO und Bibliotheken bieten eine Form von Fortsetzungen.

22
Rainer Joswig

Hier ist ein gutes Video mit einem Vergleich von Schema (Schläger meistens) und Clojure .

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

Außerdem kann Clojure nur mit recur einen ordnungsgemäßen Tail-Aufruf durchführen. Dies ist der Nachteil des Kompilierens in JVM.

Beachten Sie, dass recur das einzige nicht stapelaufwendige Schleifenkonstrukt in Clojure ist. Es gibt keine Tail-Call-Optimierung und von der Verwendung von Self-Calls zum Durchlaufen unbekannter Grenzen wird abgeraten. recur ist funktionsfähig und seine Verwendung in der Endposition wird vom Compiler überprüft. ( Sonderformen ).

10
Daniil