Frage Clojure gegen andere Lisps [geschlossen]


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

Ich habe mehrere Bücher über Clojure gelesen (Programmierung Clojure, Praktische Clojure, Die Freude der Clojureund die Manning Early Access Edition von Clojure in Aktion), und ich denke, es ist eine fantastische Sprache. Ich lese gerade Über Lambda lassen Das betrifft hauptsächlich Common-Lisp-Makros und ist auch eine sehr interessante Sprache.

ich bin nicht ein 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, hochperformante Sprachumgebung, die Suns Traum von "Write once, run [fast] anywhere" ziemlich gut erfüllt. Ich kann Code auf meinem Macbook Pro schreiben, ihn in eine ausführbare JAR-Datei kompilieren und dann unter Linux und Microsoft Windows mit wenig zusätzlichen Tests 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 in Java.

    • Standard, 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 Lesemakros zu CL hinzufügen können.

Nachteile von Clojure:

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

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

  • Benutzerdefinierbare Lesermakros.

  • Andere Vorteile?

Gedanken? Andere Unterschiede?


76


Ursprung


Antworten:


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

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

  • Sehr gute Java-Interoperabilität - bietet Kompatibilität mit der großen Auswahl an Bibliotheken im Java / JVM-Ökosystem. Ich habe Clojure als eine "Leim" -Sprache verwendet, um verschiedene Java-Bibliotheken mit guter Wirkung zu verbinden. Da ich auch eine Menge Java-Code entwickle, ist es hilfreich für mich, dass Clojure gut in Java-Tools integriert ist (z. B. verwende ich Maven, Eclipse mit Counterclockwise-Plugin für meine Clojure-Entwicklung).

  • Nette Syntax für Vektoren [1 2 3], Karten {:bob 10, :jane 15} und Sätze #{"a" "b" "c"} - Ich halte diese ziemlich essentiellen Werkzeuge für die moderne Programmierung (neben Listen natürlich!)

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

  • Der Schwerpunkt liegt auf lässiger, funktionaler Programmierung mit persistenten, unveränderlichen Datenstrukturen - insbesondere alle Kern-Clojure-Bibliotheken unterstützen dies standardmäßig

  • Hervorragende STM-Implementierung für Multicore-Concurrency. Ich glaube, dass Clojure im Moment die beste Nebenläufigkeitsgeschichte aller Sprachen hat (siehe dazu) Video für weitere Ausarbeitung von Rich Hickey selbst)

  • Es ist ein Lisp-1 (wie Scheme), das ich persönlich bevorzuge (ich denke in einer funktionalen Sprache macht es Sinn, Funktionen und Daten im selben Namensraum zu behalten)


44



Ein wichtiger Unterschied zwischen Clojure und Common Lisp ist, dass Clojure mehr über funktionale Programmierung schreibt. Clojures Philosophie, Idiome und bis zu einem gewissen Grad Sprache / Bibliotheken ermutigen und bestehen manchmal darauf, dass Sie auf eine funktionale Weise programmieren (keine Nebenwirkungen, kein veränderbarer Zustand).

Common Lisp unterstützt auf jeden Fall die funktionale Programmierung, erlaubt aber auch die Programmierung von veränderbarem Zustand und Imperativ.

Natürlich gibt es eine Reihe von Vorteilen für die funktionale Programmierung, sowohl im Bereich der Nebenläufigkeit als auch sonst. Aber 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 nicht zwingend die imperative Programmierung, aber es ist weniger bereit für diesen Stil als Common Lisp.


23



Denken Sie daran, dass Clojure eine Sprache und eine Implementierung ist (normalerweise auf der JVM). Common Lisp ist eine Sprache mit mehr als zehn verschiedenen Implementierungen. Also haben wir hier ein Kategorieninkasso. Sie könnten zum Beispiel Clojure mit SBCL vergleichen.

Allgemein:

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

  • die meisten anderen Common-Lisp-Implementierung nicht

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

  • Common Lisp hat Syntax für Arrays. Syntax für andere Datentypen kann vom Benutzer geschrieben werden und wird von verschiedenen Bibliotheken zur Verfügung gestellt.

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


19



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

Um fair zu sein, Racket hat Syntax Zucker (zusätzliche Reader Stuff) auch für Datentypen (#hash, #, eckige Klammern, etc.)

Außerdem ist Clojures einziger Weg, einen richtigen Schwanz zu verwenden, zu benutzen recur, das ist der Nachteil der Kompilierung zu JVM.

Beachten Sie, dass recur ist das einzige nicht stapelaufbauende Schleifenkonstrukt in Clojure. Es gibt kein Tail-Call   Die Optimierung und die Verwendung von Selbstaufrufen zum Schleifen unbekannter Grenzen wird abgeraten. recur ist   funktional und seine Verwendung in der Endposition wird vom Compiler überprüft. (Spezielle Formen).


10