Was sind die tatsächlichen Unterschiede zwischen Scheme und Common Lisp? (Oder zwei andere Dialekte von Lisp)

78

Hinweis: Ich frage nicht, was ich lernen soll, was besser ist oder so etwas.

Ich habe die kostenlose Version von SICP aufgenommen, weil ich dachte, es wäre schön zu lesen (ich habe gute Sachen darüber gehört und bin an dieser Art von Programmierung interessiert).

Ich weiß, dass Scheme ein Dialekt von Lisp ist, und ich habe mich gefragt: Was ist der tatsächliche Unterschied zwischen Scheme und beispielsweise Common Lisp?

Es scheint viel über "CL hat eine größere Standardlib ... Schema ist nicht gut für die Programmierung in der realen Welt ..." zu sein, aber keine tatsächliche Aussage "Das liegt daran, dass CL dies ist / hat".

Die kommunistische Ente
quelle
4
"Schema ist nicht gut für die reale Programmierung" ... Ich programmiere in der realen Welt in Schema (ok, nicht viel).
Knivil
Ich bin mir nicht sicher, ob dies der Untertext ist, aber ich würde empfehlen, nur die SICP-Übungen in Schema durchzuführen. Sie können nahezu jede Implementierung mit den richtigen Parametern verwenden, da die Teilmenge, auf die sie sich konzentrieren, so klein ist. Sie müssten nur die richtigen Parameter für Ihre Wahl finden, zum Beispiel in Racket wäre es wahrscheinlich der R5RS-Modus. Viele Ideen von SICP helfen Ihnen bei Ihrer weiteren Lisp-Studie, auch wenn Sie stattdessen Common Lisp oder sogar Clojure verwenden.
michiakig
11
Zuletzt habe ich gesehen, dass die Schema-Spezifikation ungefähr 50 Seiten und die CL-Spezifikation über 1000 Seiten umfasste. Öffnen Sie also einfach die CL-Spezifikation für jede Seite, und die Chancen stehen gut, dass dies in CL, aber nicht in Schema enthalten ist. :-)
Ken
@knivil Ich zitierte aus anderen SO-Fragen, die ich gesehen habe, welche ich verwenden soll.
Die kommunistische Ente
mögliches Duplikat von Common Lisp oder Scheme?
Nawfal

Antworten:

99

Dies ist eine etwas knifflige Frage, da die Unterschiede sowohl technischer als auch (was meiner Meinung nach wichtiger ist) kultureller Natur sind. Eine Antwort kann immer nur eine ungenaue, subjektive Sichtweise liefern. Dies werde ich hier bereitstellen. Einige technische Details finden Sie im Schema-Wiki .

Scheme ist eine Sprache, die auf dem Prinzip basiert, ein elegantes, konsistentes und durchdachtes Basissprachensubstrat bereitzustellen, auf dem sowohl praktische als auch akademische Anwendungssprachen aufbauen können.

Selten werden Sie jemanden finden, der eine Anwendung im reinen R5RS- (oder R6RS-) Schema schreibt, und aufgrund des minimalistischen Standards ist der meiste Code nicht über Schema-Implementierungen hinweg portierbar. Dies bedeutet, dass Sie Ihre Schema-Implementierung sorgfältig auswählen müssen, wenn Sie eine Art Endbenutzeranwendung schreiben möchten, da die Auswahl weitgehend bestimmt, welche Bibliotheken Ihnen zur Verfügung stehen. Andererseits bedeutet die relative Freiheit beim Entwerfen der tatsächlichen Anwendungssprache, dass Schemaimplementierungen häufig Funktionen bereitstellen, die anderswo unbekannt sind. Mit PLT Racket können Sie beispielsweise statische Typisierung verwenden und eine sehr sprachbewusste IDE bereitstellen.

Interoperabilität über die Basissprache hinaus wird durch den Community-gesteuerten SRFI-Prozess bereitgestellt, die Verfügbarkeit eines bestimmten SRFI variiert jedoch je nach Implementierung.

Die meisten Schemadialekte und -bibliotheken konzentrieren sich auf funktionale Programmiersprachen wie Rekursion statt Iteration. Es gibt verschiedene Objektsysteme, die Sie als Bibliotheken laden können, wenn Sie OOP ausführen möchten. Die Integration in vorhandenen Code hängt jedoch stark vom Scheme-Dialekt und seiner umgebenden Kultur ab (Chicken Scheme scheint objektorientierter zu sein als beispielsweise Racket).

Die interaktive Programmierung ist ein weiterer Punkt, in dem sich die Untergemeinschaften des Schemas unterscheiden. Das MIT-Schema ist für seine starke Interaktivitätsunterstützung bekannt, während sich PLT Racket viel statischer anfühlt. Auf jeden Fall scheint die interaktive Programmierung für die meisten Untergemeinschaften des Schemas kein zentrales Anliegen zu sein, und ich habe noch keine Programmierumgebung gesehen, die ähnlich interaktiv ist wie die der meisten Common Lisps.

Common Lisp ist eine vom Kampf getragene Sprache, die für die praktische Programmierung entwickelt wurde. Es ist voller hässlicher Warzen und Kompatibilitäts-Hacks - ganz im Gegenteil zu Schemes elegantem Minimalismus. Aber es ist auch viel nützlicher, wenn es für sich genommen wird.

Common Lisp hat ein relativ großes Ökosystem tragbarer Bibliotheken hervorgebracht. Normalerweise können Sie die Implementierung auch nach der Anwendungsbereitstellung jederzeit ohne allzu große Probleme wechseln. Insgesamt ist Common Lisp viel einheitlicher als das Schema, und radikalere Sprachexperimente werden, wenn überhaupt, normalerweise als tragbare Bibliothek eingebettet, anstatt einen ganz neuen Sprachdialekt zu definieren. Aus diesem Grund sind Spracherweiterungen eher konservativ, aber auch kombinierbarer (und oft optional).

Universell nützliche Spracherweiterungen wie Schnittstellen für Fremdfunktionen werden nicht auf formalem Wege entwickelt, sondern basieren auf Quasi-Standardbibliotheken, die auf allen wichtigen Common Lisp-Implementierungen verfügbar sind.

Die Sprachsprachen sind eine wilde Mischung aus funktionalen, imperativen und objektorientierten Ansätzen, und im Allgemeinen fühlt sich Common Lisp eher wie eine imperative als wie eine funktionale Sprache an. Es ist auch äußerst dynamisch, wahrscheinlich mehr als jede der gängigen dynamischen Skriptsprachen (die Neudefinition von Klassen gilt beispielsweise für vorhandene Instanzen, und das Bedingungssystem hat eine integrierte Interaktivität), und interaktive, explorative Programmierung ist ein wichtiger Bestandteil von "der Common Lisp Weg." Dies spiegelt sich auch in den für Common Lisp verfügbaren Programmierumgebungen wider, die praktisch alle eine direkte Interaktion mit dem laufenden Lisp-Compiler bieten.

Common Lisp verfügt über ein integriertes Objektsystem (CLOS), ein Zustandsbehandlungssystem, das wesentlich leistungsfähiger ist als die bloße Ausnahmebehandlung, Laufzeit-Patchbarkeit und verschiedene Arten von integrierten Datenstrukturen und -nutzungszwecken (einschließlich des berüchtigten LOOP- Makros, einer Iteration) Sublanguage viel zu hässlich für Scheme, aber viel zu nützlich, um es nicht zu erwähnen, sowie ein printf-ähnlicher Formatierungsmechanismus mit GOTO-Unterstützung in Format-Strings.

Sowohl aufgrund der bildbasierten, interaktiven Entwicklung als auch aufgrund der größeren Sprache sind Lisp-Implementierungen in der Regel betriebssystemübergreifend weniger portabel als Schema-Implementierungen. Das Ausführen eines Common Lisp auf einem eingebetteten Gerät ist beispielsweise nichts für schwache Nerven. Ähnlich wie bei der Java Virtual Machine treten auch bei Maschinen mit eingeschränktem virtuellem Speicher (z. B. OpenVZ-basierten virtuellen Servern) Probleme auf. Schemaimplementierungen sind dagegen tendenziell kompakter und portabler. Die zunehmende Qualität der ECL-Implementierung hat diesen Punkt etwas gemildert, obwohl sein Wesen immer noch wahr ist.

Wenn Sie sich für kommerziellen Support interessieren, gibt es einige Unternehmen, die ihre eigenen Common Lisp-Implementierungen anbieten, darunter grafische GUI-Builder, spezialisierte Datenbanksysteme usw.

Zusammenfassend ist Scheme eine eleganter gestaltete Sprache. Es ist in erster Linie eine funktionale Sprache mit einigen dynamischen Merkmalen. Seine Implementierungen repräsentieren verschiedene inkompatible Dialekte mit besonderen Merkmalen. Common Lisp ist eine vollwertige, hochdynamische Multi-Paradigmen-Sprache mit verschiedenen hässlichen, aber pragmatischen Merkmalen, deren Implementierungen weitgehend miteinander kompatibel sind. Schemadialekte sind in der Regel statischer und weniger interaktiv als Common Lisp. Gängige Lisp-Implementierungen sind in der Regel schwerer und schwieriger zu installieren.

Egal für welche Sprache Sie sich entscheiden, ich wünsche Ihnen viel Spaß! :) :)

Matthias Benkard
quelle
7
should you want to write some kind of end-user application+1
kmoe
21

Einige grundlegende praktische Unterschiede:

  • Common Lisp verfügt über separate Bereiche für Variablen und Funktionen. Während es in Schema nur einen Bereich gibt - Funktionen sind Werte und das Definieren einer Funktion mit einem bestimmten Namen definiert nur eine Variable, die auf das Lambda gesetzt ist. Infolgedessen können Sie in Schema einen Funktionsnamen als Variable verwenden und ihn speichern oder an andere Funktionen übergeben und dann einen Aufruf mit dieser Variablen ausführen, als wäre es eine Funktion. In Common Lisp müssen Sie jedoch eine Funktion mit explizit in einen Wert konvertieren und eine in einem Wert (function ...)gespeicherte Funktion mit explizit aufrufen(funcall ...)
  • In Common Lisp wird nil(die leere Liste) als falsch (z. B. in if) betrachtet und ist der einzige falsche Wert. In Schema wird die leere Liste als wahr betrachtet und (die eindeutige) #fist der einzige falsche Wert
newacct
quelle
Für mich ist der erste Punkt, den @newacct macht, bei weitem der wichtigste. Wenn Funktionen keine erstklassigen Objekte sind, geht mir ein Großteil des wirklich lustigen, "kreativen" Programmiergefühls verloren. OK, es mag "praktische" Überlegungen zur Geschwindigkeit usw. geben, aber wenn ich eine funktionale, unveränderliche Programmierung möchte, gibt es meiner Meinung nach einfach keinen Vergleich. Und wenn ich Praktikabilität will, kann ich nach Clojure gehen und das Beste aus beiden Welten bekommen. Common Lisp hat seinen Platz, aber ich vermute, dass dies in der Welt der "Industrie" der Fall ist, in der die Leute sicher sehr dankbar dafür sind.
Alex Gian
2
CL hat immer noch erstklassige Funktionen. Dass es einen separaten Namespace für Funktionen gibt, bedeutet nicht, dass es keine erstklassigen Funktionen hat (ja, es ist etwas mehr Syntax erforderlich, aber das ist alles ).
Mwal
re: funktional in CL, größeres Hindernis ist das Fehlen obligatorischer TCO. Sicher, einige Implementierungen unterstützen dies, aber dann bedeutet dies, dass Sie keinen tragbaren CL-Code mehr schreiben und die Portabilität einer der Hauptgründe ist
Coderino Javarino,
8

Diese Frage ist schwer unparteiisch zu beantworten, insbesondere weil viele der LISP-Leute das Schema als LISP klassifizieren würden.

Josh Bloch (und diese Analogie ist möglicherweise nicht seine Erfindung) beschreibt die Auswahl einer Sprache als ähnlich wie die Auswahl eines lokalen Pubs. In diesem Licht also:

In der Kneipe "Scheme" gibt es viele Forscher in Programmiersprachen. Diese Leute legen viel Wert auf die Bedeutung der Sprache, darauf, sie klar und einfach zu halten und innovative neue Funktionen zu diskutieren. Jeder hat seine eigene Version der Sprache, mit der er seine eigene Ecke der Programmiersprachen erkunden kann. Die Scheme-Leute mögen die Syntax in Klammern, die sie von LISP übernommen haben, sehr. Es ist flexibel und leicht und einheitlich und beseitigt viele Hindernisse für die Spracherweiterung.

Die "LISP" Kneipe? Nun ... ich sollte nicht kommentieren; Ich habe dort nicht genug Zeit verbracht :).

John Clements
quelle
2

planen:

  • ursprünglich nur sehr wenige Spezifikationen (neuer R7RS scheint schwerer zu sein)
  • Aufgrund der einfachen Syntax kann das Schema schnell erlernt werden
  • Implementierungen bieten zusätzliche Funktionen, aber die Namen können in verschiedenen Implementierungen unterschiedlich sein

gemeinsames lisp:

  • Viele Funktionen werden durch die größere Spezifikation definiert
  • unterschiedlicher Namespace für Funktionen und Variablen (lisp-2)

Das sind einige Punkte, sicher gibt es noch viele weitere, an die ich mich momentan nicht erinnere.

Moe
quelle
1
Sie beziehen sich auf "RSR7"; Dies sollte stattdessen "R6RS" sein.
John Clements