Common Lisp
Paradigma | Multi-Paradigma: prozedural, funktional, objektorientierter, Meta, reflektierend, generisch |
---|---|
Familie | Lispeln |
Entworfen von | Scott Fahlman, Richard P. Gabriel, David A. Moon, Kent Pitman, Guy Steele, Dan Weinreb |
Entwickler | Ansi X3j13 Komitee |
Erstmals erschienen | 1984 | , 1994 Für ANSI Common Lisp
Disziplin tippen | Dynamisch, stark |
Zielfernrohr | Lexikalisch, optional dynamisch |
OS | Plattformübergreifend |
Dateiname -Erweiterungen | .lisp, .lsp, .l, .cl, .fasl |
Webseite | Common-LISP |
Haupt Implementierungen | |
Allegro Cl, Abcl, Cliv, Clozure Cl, Cmucl, ECL, GCL, Lispworks, Scieneer CL, SBCL, Symbolics Common Lisp | |
Dialekte | |
CLTL1, CLTL2, ANSI Common Lisp | |
Beeinflusst von | |
Lispeln, Lisp Machine Lisp, MacLisp, Planen, Interisp | |
Beeinflusst | |
Clojure, Dylan, EMACS Lisp, EULISP, ISLISP, *Lispeln, Autolisp, Julia, Elch, R, KÖNNEN, Subl |
Common Lisp (Cl) ist ein Dialekt der Lisp -Programmiersprache, veröffentlicht in Ansi Standarddokument ANSI Incits 226-1994 (S20018)[1] (früher X3.226-1994 (R1999)).[2] Das Common Lisp hyperspecEine hyperlinke HTML -Version wurde vom ANSI Common Lisp -Standard abgeleitet.[3]
Die gemeinsame Lisp -Sprache wurde als standardisierter und verbesserter Nachfolger von entwickelt MacLisp. In den frühen 1980er Jahren arbeiteten bereits mehrere Gruppen an verschiedenen Nachfolgern von MacLisp: Lisp Machine Lisp (auch bekannt als Zetalisp), Spice Lisp, NULL und S-1 Lisp. Common Lisp versuchte, die Merkmale dieser Maclisp -Dialekte zu vereinen, zu standardisieren und zu erweitern. Common Lisp ist keine Implementierung, sondern eine Sprache Spezifikation.[4] Mehrere Implementierungen des gemeinsamen Lisp -Standards sind verfügbar, einschließlich Kostenlose und Open-Source-Software und proprietäre Produkte.[5] Gemeinsames Lisp ist ein allgemeiner Zwecke, Multi-Paradigm-Programmiersprache. Es unterstützt eine Kombination von prozedural, funktional, und Objekt orientierte Programmierung Paradigmen. Als ein Dynamische Programmiersprache, es erleichtert evolutionär und Inkrementelle Softwareentwicklungmit iterativ Zusammenstellung in effiziente Laufzeitprogramme. Diese inkrementelle Entwicklung erfolgt häufig interaktiv, ohne die laufende Anwendung zu unterbrechen.
Es unterstützt auch optionale Typanmerkungen und Casting, die nach Bedarf zu später hinzugefügt werden können Profilerstellung und Optimierungsphasen, damit der Compiler effizientere Code generieren kann. Zum Beispiel, Fixnum
kann an halten ungeblieben Ganzzahl in einem Bereich, der von der Hardware und Implementierung unterstützt wird und eine effizientere Arithmetik als bei großen Ganzzahlen oder willkürlichen Präzisionstypen ermöglicht. In ähnlicher Weise kann der Compiler auf einer Basis pro Modul oder pro Funktion mitgewählt werden, welche Art von Sicherheitsniveau gewünscht wird, und es wird gewünscht optimieren Erklärungen.
Common Lisp inklusive Schloss, ein Objektsystem Das unterstützt Multimethods und Methodenkombinationen. Es wird oft mit a implementiert MetaObject Protokoll.
Common Lisp wird durch Standardmerkmale wie z. Lispeln Makros (Code -Transformationen) und Leser -Makros (Eingeben Sie Parser für Zeichen).
Common Lisp bietet eine teilweise Rückwärtskompatibilität mit MacLisp und John McCarthys Original Lispeln. Auf diese Weise kann die ältere Lisp -Software auf Common LISP portiert werden.[6]
Geschichte
Die Arbeit an Common Lisp begann 1981 nach einer Initiative des ARPA -Managers Bob Engelmore, um einen einzigen Community -Standard -LISP -Dialekt zu entwickeln.[7] Ein Großteil des anfänglichen Sprachdesigns wurde per E -Mail durchgeführt.[8][9] 1982,, Guy L. Steele Jr. gab den ersten Überblick über Common Lisp auf dem ACM -Symposium von 1982 über Lisp und funktionelle Programmierung.[10]
Die Erster Sprachdokumentation wurde 1984 als veröffentlicht als Gemeinsam lispeln die Sprache (bekannt als CLTL1), Erstausgabe. Eine zweite Ausgabe (bekannt als CLTL2), die 1990 veröffentlicht wurde, umfasste viele Änderungen der Sprache, die während des ANSI Common Lisp Standardisierungsprozesses vorgenommen wurde: Extended Loop -Syntax, das gemeinsame LiSP -Objektsystem, das Bedingungensystem für Fehlerbehandlung, eine Schnittstelle zu Schöner Drucker und vieles mehr. CLTL2 beschreibt jedoch nicht den endgültigen ANSI Common Lisp -Standard und ist daher keine Dokumentation von ANSI Common Lisp. Der endgültige ANSI Common Lisp -Standard wurde dann 1994 veröffentlicht. Seitdem wurde kein Update des Standards veröffentlicht. Verschiedene Erweiterungen und Verbesserungen des gemeinsamen LISP (Beispiele sind Unicode, Parallelität, CLOs-basierte IO) wurden von Implementierungen und Bibliotheken bereitgestellt.
Syntax
Common Lisp ist ein Dialekt von Lisp. Es verwendet S-Expressionen sowohl Code als auch Datenstruktur zu bezeichnen. Funktionsaufrufe, Makroformulare und spezielle Formulare werden als Listen geschrieben, wobei der Name des Bedieners zuerst wie in diesen Beispielen:
(+ 2 2) ; Fügt 2 und 2 hinzu, die 4. Der Name der Funktion ist '+'. LISP hat keine Betreiber als solche.
(Defvar *x*) ; Stellt sicher, dass eine Variable * x * existiert, ; ohne ihm einen Wert zu geben. Die Sternchen sind Teil von ; Der Name nach Übereinkommen, die eine spezielle (globale) Variable bezeichnet. ; Das Symbol * x * wird hiermit auch mit der Eigenschaft ausgestattet, die ; Nachfolgende Bindungen davon sind eher dynamisch als lexikalisch. (setf *x* 42.1) ; Legt die Variable * x * auf den Gleitpunktwert 42.1 fest
;; Definieren Sie eine Funktion, die eine Zahl auf dem Markt dreht: (Defun Quadrat (x) (* x x))
;; Führen Sie die Funktion aus: (Quadrat 3) ; Gibt 9 zurück
;; Das Konstrukt "Let" erstellt einen Umfang für lokale Variablen. Hier ;; Die Variable 'A' ist an 6 gebunden und die Variable 'B' ist gebunden ;; bis 4. innerhalb des 'let' befindet sich ein "Körper", wo der zuletzt berechnete Wert zurückgegeben wird. ;; Hier wird das Ergebnis des Hinzufügens von A und B aus dem Ausdruck "Let" zurückgegeben. ;; Die Variablen A und B haben einen lexikalischen Bereich, es sei denn, die Symbole waren ;; Markiert als spezielle Variablen (zum Beispiel durch eine vorherige Defvar). (Lassen ((a 6) (b 4)) (+ a b)) ; Gibt 10 zurück
Datentypen
Common Lisp hat viele Datentypen.
Skalartypen
Nummer Typen enthalten Ganzzahlen, Verhältnisse, Gleitkommazahlen, und komplexe Zahlen.[11] Gemeinsame Lisp -Verwendungen Bignums Um numerische Werte willkürlicher Größe und Präzision darzustellen. Der Verhältnisstyp repräsentiert Fraktionen genau, eine Einrichtung, die in vielen Sprachen nicht verfügbar ist. Common Lisp zwingt automatisch numerische Werte zwischen diesen Typen.
Das gemeinsame Lisp Charakter Typ ist nicht beschränkt auf ASCII Figuren. Die meisten modernen Implementierungen erlauben es Unicode Figuren.[12]
Das Symbol Typ ist bei Lisp -Sprachen gemeinsam, aber außerhalb ihnen weitgehend unbekannt. Ein Symbol ist ein eindeutiges Datenobjekt mit mehreren Teilen: Name, Wert, Funktion, Eigenschaftsliste und Paket. Von diesen, Wertzelle und Funktionszelle sind die wichtigsten. Symbole in LISP werden häufig ähnlich wie Identifikatoren in anderen Sprachen verwendet: den Wert einer Variablen zu halten; Es gibt jedoch viele andere Verwendungen. Normalerweise wird sein Wert zurückgegeben, wenn ein Symbol bewertet wird. Einige Symbole bewerten sich beispielsweise alle Symbole im Schlüsselwortpaket selbstbewertend. Boolesche Werte in gemeinsamen LISP werden durch die selbstbewertenden Symbole t und Nil dargestellt. Common Lisp hat Namespaces für Symbole, die als "Pakete" bezeichnet werden.
Eine Reihe von Funktionen stehen für verfügbar für Rundung skalare numerische Werte auf verschiedene Weise. Die Funktion runden
Runden das Argument an die nächste Ganzzahl, wobei die Hälfte der Hälfte an die gleichmäßige Ganzzahl gerundet ist. Die Funktionen kürzen
, Boden
, und Decke
Rund in Richtung Null, unten oder nach oben. Alle diese Funktionen geben den weggeworfenen Bruchteil als sekundärer Wert zurück. Zum Beispiel, (Boden -2.5)
ergibt –3, 0,5; (Decke -2,5)
ergibt –2, –0,5; (Runde 2.5)
ergibt 2, 0,5; und (Runde 3.5)
ergibt 4, –0,5.
Datenstrukturen
Reihenfolge Zu den gemeinsamen LISP-Typen gehören Listen, Vektoren, Bitvektoren und Saiten. Es gibt viele Operationen, die an jedem Sequenztyp funktionieren können.
Wie in fast allen anderen Lisp -Dialekten, Listen in gemeinsamer Lisp bestehen aus konsultiert, manchmal genannt Cons -Zellen oder Paare. A CONS ist eine Datenstruktur mit zwei Slots, die als ihre bezeichnet werden Wagen und CDR. Eine Liste ist eine verknüpfte Kette von Konzern oder die leere Liste. Jedes Auto -Auto bezieht sich auf ein Mitglied der Liste (möglicherweise eine andere Liste). Der CDR von jedem Cons bezieht sich auf den nächsten Nachteil - außer für die letzten Nachteile in einer Liste, deren CDR auf die bezieht Null
Wert. CONS kann auch leicht zur Implementierung von Bäumen und anderen komplexen Datenstrukturen verwendet werden. Es wird jedoch normalerweise empfohlen, stattdessen Struktur- oder Klasseninstanzen zu verwenden. Es ist auch möglich, kreisförmige Datenstrukturen mit conse zu erstellen.
Gemeinsame Lisp -Unterstützungen mehrdimensional Arraysund kann dynamisch ändern einstellbar Arrays bei Bedarf. Mehrdimensionale Arrays können für die Matrixmathematik verwendet werden. EIN Vektor ist ein eindimensionales Array. Arrays können jede Art als Mitglieder (sogar gemischte Typen im selben Array) tragen oder auf eine bestimmte Art von Mitgliedern wie in einem Vektor von Bits spezialisiert sein. Normalerweise werden nur wenige Typen unterstützt. Viele Implementierungen können Array-Funktionen optimieren, wenn das verwendete Array typisch speziell ist. Zwei typspezialisierte Array-Typen sind Standard: a Saite ist ein Vektor von Charakteren, während a Bitvektor ist ein Vektor von Bits.
Hash -Tische Speichern Sie Assoziationen zwischen Datenobjekten. Jedes Objekt kann als Schlüssel oder Wert verwendet werden. Hash -Tabellen werden nach Bedarf automatisch geändert.
Pakete sind Sammlungen von Symbolen, die hauptsächlich verwendet werden, um die Teile eines Programms zu trennen Namespaces. Ein Paket Mai Export Einige Symbole, die sie als Teil einer öffentlichen Schnittstelle markieren. Pakete können andere Pakete verwenden.
Strukturen, ähnlich in gebrauchten zu C Strukturen und Pascal Datensätze, darstellen beliebige komplexe Datenstrukturen mit einer beliebigen Anzahl und Art von Feldern (genannt Schlüssel). Strukturen ermöglichen eine Single-Ineritanz.
Klassen ähneln Strukturen, bieten jedoch dynamischere Merkmale und mehreren Ineritanzen. (Sehen Schloss). Der Unterricht wurde zu spät zu Common Lisp hinzugefügt, und es gibt einige konzeptionelle Überschneidungen mit Strukturen. Objekte, die von Klassen erstellt wurden, werden genannt Instanzen. Ein Sonderfall sind generische Funktionen. Generische Funktionen sind sowohl Funktionen als auch Instanzen.
Funktionen
Gemeinsame Lisp -Stützen erstklassige Funktionen. Zum Beispiel ist es möglich, Funktionen zu schreiben, die auch andere Funktionen als Argumente oder Rückgabefunktionen annehmen. Dies ermöglicht es, sehr allgemeine Operationen zu beschreiben.
Die gemeinsame LiSP-Bibliothek stützt sich stark von solchen Funktionen höherer Ordnung. Zum Beispiel die Sortieren
Funktion nimmt a relationaler Operator Als Argument und Schlüsselfunktion als optionales Schlüsselwortargument. Dies kann nicht nur verwendet werden, um eine Art von Daten zu sortieren, sondern auch Datenstrukturen nach einem Schlüssel zu sortieren.
;; Sortiert die Liste mit der> und <Funktion als relationaler Operator. (Sortieren (aufführen 5 2 6 3 1 4) #'>) ; Rückgabe (6 5 4 3 2 1) (Sortieren (aufführen 5 2 6 3 1 4) #'<) ; Rückgabe (1 2 3 4 5 6)
;; Sortiert die Liste nach dem ersten Element jeder Unterliste. (Sortieren (aufführen '(9 A) '(3 B) '(4 C)) #'< :Schlüssel #'Erste) ; Rückgabe ((3 b) (4 c) (9 a))
Das Bewertungsmodell für Funktionen ist sehr einfach. Wenn der Evaluator auf ein Formular stößt (f a1 a2 ...)
Dann setzt es voraus, dass das Symbol mit dem Namen F einer der folgenden ist:
- Ein spezieller Bediener (leicht gegen eine feste Liste überprüft)
- Ein Makrooperator (muss zuvor definiert worden sein)
- Der Name einer Funktion (Standard), die entweder ein Symbol sein kann, oder eine Unterform, die mit dem Symbol beginnt
Lambda
.
Wenn f der Name einer Funktion ist, werden die Argumente A1, A2, ..., A in der Reihenfolge von links nach rechts bewertet, und die Funktion wird mit den als Parametern gelieferten Werte gefunden und aufgerufen.
Funktionen definieren
Das Makro Defun
Definiert Funktionen, bei denen eine Funktionsdefinition den Namen der Funktion, die Namen aller Argumente und eine Funktionskörper angibt:
(Defun Quadrat (x) (* x x))
Funktionsdefinitionen können Compiler einschließen Richtlinien, bekannt als Erklärungen, die dem Compiler Hinweise auf Optimierungseinstellungen oder die Datentypen von Argumenten geben. Sie können auch einschließen Dokumentationszeichenfolgen (Docstrings), mit dem das Lisp -System interaktive Dokumentation bereitstellt:
(Defun Quadrat (x) "Berechnet das Quadrat des Einzelflecks x." (erklären (Einflüssigkeit x) (optimieren (Geschwindigkeit 3) (debuggen 0) (Sicherheit 1))) (das Einflüssigkeit (* x x)))
Anonyme Funktionen (Funktionsliterale) werden definiert verwendet Lambda
Ausdrücke, z. (lambda (x) (*x x))
für eine Funktion, die ihr Argument enthält. Der LiSP-Programmierstil verwendet häufig Funktionen höherer Ordnung, für die es nützlich ist, anonyme Funktionen als Argumente zu liefern.
Lokale Funktionen können definiert werden mit flet
und Etiketten
.
(flet ((Quadrat (x) (* x x))) (Quadrat 3))
Es gibt mehrere andere Operatoren, die sich auf die Definition und Manipulation von Funktionen beziehen. Zum Beispiel kann eine Funktion mit dem kompiliert werden kompilieren
Operator. (Einige LISP -Systeme laufen standardmäßig mit einem Dolmetscher aus, es sei denn, es werden angewiesen, zu kompilieren; andere kompilieren jede Funktion).
Definieren generischer Funktionen und Methoden
Das Makro Defgenerisch
Definiert generische Funktionen. Generische Funktionen sind eine Sammlung von Methoden. Das Makro Defmethod
definiert Methoden.
Methoden können ihre Parameter über Clos spezialisieren Standardklassen, Systemklassen, Strukturklassen oder einzelne Objekte. Für viele Typen gibt es entsprechend Systemklassen.
Wenn eine generische Funktion aufgerufen wird, Mehrfachdispatch Bestimmt die zu verwendende effektive Methode.
(Defgenerisch hinzufügen (a b))
(Defmethod hinzufügen ((a Nummer) (b Nummer)) (+ a b))
(Defmethod hinzufügen ((a Vektor) (b Nummer)) (Karte 'Vektor (Lambda (n) (+ n b)) a))
(Defmethod hinzufügen ((a Vektor) (b Vektor)) (Karte 'Vektor #'+ a b))
(Defmethod hinzufügen ((a Saite) (b Saite)) (verketten 'String a b))
(hinzufügen 2 3) ; Gibt 5 zurück (hinzufügen #(1 2 3 4) 7) ; Gibt #(8 9 10 11) zurück (hinzufügen #(1 2 3 4) #(4 3 2 1)) ; Rückgabe #(5 5 5 5) (hinzufügen "GEMEINSAMES " "LISPELN") ; Gibt "Common Lisp" zurück "
Generische Funktionen sind auch a First -Class -Datentyp. Generische Funktionen und Methoden als oben beschrieben haben viel mehr Funktionen.
Der Funktionsnamenspace
Der Namespace für Funktionsnamen ist vom Namespace für Datenvariablen getrennt. Dies ist ein wichtiger Unterschied zwischen dem gemeinsamen Lisp und einem Planen. Für gemeinsame LISP gehören Bediener, die Namen im Funktionsnamenspace definieren Defun
, flet
, Etiketten
, Defmethod
und Defgenerisch
.
Um eine Funktion mit Namen als Argument an eine andere Funktion zu übergeben, muss man die verwenden Funktion
Spezialbetreiber, häufig abgekürzt als #'
. Der Erste Sortieren
Beispiel oben bezieht sich auf die vom Symbol benannte Funktion >
im Funktionsnamenspace mit dem Code #'>
. Umgekehrt würde man die verwenden, um eine Funktion so zu bezeichnen Funcall
Operator auf dem Argument.
Schema Das Bewertungsmodell ist einfacher: Es gibt nur einen Namespace, und alle Positionen im Formular werden (in beliebiger Reihenfolge) bewertet - nicht nur die Argumente. Der in einem Dialekt geschriebene Code ist daher für Programmierer, die im anderen erfahrene erfahrene, manchmal verwirrend. Zum Beispiel verwenden viele gemeinsame LISP -Programmierer gerne beschreibende variable Namen wie z. aufführen oder Saite Dies könnte zu Problemen im Schema führen, wie sie die Namen der Schattenfunktion lokal schatten.
Ob ein separater Namespace für Funktionen ein Vorteil ist, ist eine Quelle der Streitquellen in der LISP -Community. Es wird normalerweise als die bezeichnet LISP-1 vs. Lisp-2-Debatte. LISP-1 bezieht sich auf das Modell von Schema und LISP-2 bezieht sich auf das Common LISP-Modell. Diese Namen wurden in einem Papier von 1988 von von 1988 geprägt Richard P. Gabriel und Kent Pitman, was die beiden Ansätze umfassend vergleicht.[13]
Mehrere Rückgabewerte
Common Lisp unterstützt das Konzept von Mehrere Werte,[14] wo jeder Ausdruck immer einen einzigen hat Hauptwert, aber es könnte auch eine beliebige Anzahl von haben Sekundärwerte, die von interessierten Anrufern empfangen und inspiziert werden können. Dieses Konzept unterscheidet sich von der Rückgabe eines Listenwerts, da die Sekundärwerte vollständig optional sind und über einen dedizierten Seitenkanal übergeben werden. Dies bedeutet, dass Anrufer möglicherweise die Sekundärwerte nicht bewusst sind, wenn sie nicht benötigt werden, und es ist bequem, den Mechanismus zur Kommunikation von Informationen zu verwenden, die manchmal nützlich, aber nicht immer notwendig sind. Zum Beispiel,
- Das
KÜRZEN
Funktion[15] runden die angegebene Nummer auf eine ganze Zahl in Richtung Null. Es gibt jedoch auch einen Rest als sekundärer Wert zurück, was es sehr leicht zu bestimmen macht, welcher Wert abgeschnitten wurde. Es unterstützt auch einen optionalen Divisor -Parameter, der zur Durchführung verwendet werden kann Euklidische Division trivial:
(Lassen ((x 1266778) (y 458)) (Mehrwertbindung (Quotient Rest) (kürzen x y) (Format Null "~ A geteilt durch ~ a ist ~ ein Rest ~ a" x y Quotient Rest))) ;;;;; => "1266778 geteilt durch 458 ist 2765 Rest 408"
-
Gethash
[16] Gibt den Wert eines Schlüssels in einem zurück Assoziative Karte, oder der Standardwert ansonsten und ein sekundärer Booleschen, der angibt, ob der Wert gefunden wurde. Der Code, der sich nicht darum kümmert, ob der Wert gefunden oder bereitgestellt wurde, da der Standard ihn einfach wie IS verwenden kann, aber wenn eine solche Unterscheidung wichtig ist, kann er den sekundären Booleschen und angemessen reagieren. Beide Anwendungsfälle werden durch denselben Anruf gestützt und von beiden auch unnötig belastet oder von der anderen eingeschränkt. Wenn Sie diese Funktion auf Sprachebene haben Null Wie in anderen Sprachen.
(Defun Get-Antwort (Bibliothek) (Gethash 'Antworten Bibliothek 42)) (Defun the-Antwort-1 (Bibliothek) (Format Null "Die Antwort ist ~ a" (Get-Antwort Bibliothek))) ;;;;; Gibt "Die Antwort ist 42" zurück, wenn die Antwort nicht in der Bibliothek vorhanden ist (Defun the-Antwort-2 (Bibliothek) (Mehrwertbindung (Antworten sicher-p) (Get-Antwort Bibliothek) (wenn (nicht sicher-p) "Ich weiß nicht" (Format Null "Die Antwort ist ~ a" Antworten)))) ;;;;; Gibt "Ich weiß nicht" zurück, wenn die Antwort nicht in der Bibliothek vorhanden ist
Mehrere Werte werden durch eine Handvoll Standardformen gestützt, von denen am häufigsten die sind Mehrwertbindung
spezielle Form zum Zugriff auf Sekundärwerte und WERTE
Für die Rückgabe mehrerer Werte:
(Defun Magic-acht-Ball () "Rückgabe eine Aussichtsprädiktion mit der Wahrscheinlichkeit als sekundärer Wert" (Werte "Outlook gut" (zufällig 1.0))) ;;;;; => "Outlook Good" ;;;;; => 0,3187
Andere Arten
Andere Datentypen in gemeinsamen LISP sind:
- Pfadnamen Darstellung von Dateien und Verzeichnissen in der Dateisystem. Die Common Lisp PathName -Einrichtung ist allgemeiner als die von den meisten Betriebssystemen für Datei -Benennungskonventionen und sorgt für LISP -Programme von LISP -Programmen auf Dateien, die in verschiedenen Systemen breit tragbar sind.
- Eingang und Ausgabe Ströme Repräsentieren Sie Quellen und Senken von Binär- oder Textdaten wie Terminal- oder Open -Dateien.
- Common Lisp hat ein integriert Pseudo-Random-Zahlengenerator (PRNG). Zufallszustand Objekte repräsentieren wiederverwendbare Quellen von Pseudo-Random-Zahlen, sodass der Benutzer die PRNG säen oder eine Sequenz wiederholt.
- Bedingungen sind ein Typ, mit dem Fehler, Ausnahmen und andere "interessante" Ereignisse dargestellt werden, auf die ein Programm reagieren kann.
- Klassen sind erstklassige Objekteund sind selbst Fälle von Klassen, die genannt werden MetaObject -Klassen (Metaklasse kurz).
- Referenten sind eine Art von Objekt, die steuern, wie der Leser des Lesers des LISP den Text des Quellcodes analysiert. Durch die Steuerung des Lesungsschreibers kann der Programmierer die Syntax der Sprache ändern oder erweitern.
Zielfernrohr
Wie Programme in vielen anderen Programmiersprachen nutzen gemeinsame Lisp -Programme Namen, um sich auf Variablen, Funktionen und viele andere Arten von Entitäten zu beziehen. Benannte Referenzen unterliegen dem Spielraum.
Die Assoziation zwischen einem Namen und dem Entität, auf den sich der Name bezieht, wird als Bindung bezeichnet.
Umfang bezieht sich auf die Umstände, unter denen ein Name eine bestimmte Bindung aufweist.
Determinierungen des Umfangs
Zu den Umständen, die den Umfang des gemeinsamen LISP bestimmen, gehören:
- die Position einer Referenz innerhalb eines Ausdrucks. Wenn es sich um die Position einer Verbindung links ist, bezieht es sich auf einen speziellen Operator oder eine Makro- oder Funktionsbindung, sonst auf eine variable Bindung oder etwas anderes.
- Die Art von Ausdruck, in der die Referenz stattfindet. Zum Beispiel,
(Go x)
bedeutet Übertragungsregelung zum Beschriftenx
, wohingegen(Druck x)
bezieht sich auf die Variablex
. Beide Bereiche vonx
Kann in derselben Region des Programmtextes aktiv sein, da Tagbody -Etiketten in einem separaten Namespace von Variablennamen enthalten sein. Eine spezielle Form oder ein Makroform hat die vollständige Kontrolle über die Bedeutungen aller Symbole in seiner Syntax. Zum Beispiel in(Defklasse x (a b) ())
, eine Klassendefinition, die(a b)
ist eine Liste von Basisklassen, daher werden diese Namen im Raum der Klassennamen nachgesehen, undx
Ist kein Hinweis auf eine vorhandene Bindung, sondern der Name einer neuen Klasse, die abgeleitet wirda
undb
. Diese Tatsachen entstehen nur aus der Semantik vonDefklasse
. Die einzig generische Tatsache an diesem Ausdruck ist dasDefklasse
bezieht sich auf eine Makrobindung; Alles andere ist vorhandenDefklasse
. - Der Ort der Referenz im Programmtext. Zum Beispiel, wenn ein Verweis auf Variable
x
ist in ein Bindungskonstrukt wie a eingeschlossenLassen
das definiert eine Bindung fürx
und dann befindet sich die Referenz im Bereich, der durch diese Bindung erzeugt wird. - Für eine variable Referenz, ob ein variables Symbol lokal oder global, als speziell deklariert wurde oder nicht. Dies bestimmt, ob die Referenz in einer lexikalischen Umgebung oder in einer dynamischen Umgebung aufgelöst wird.
- Die spezifische Instanz der Umgebung, in der die Referenz gelöst wird. Eine Umgebung ist ein Laufzeitwörterbuch, das Symbole an Bindungen abbildet. Jede Art von Referenz verwendet eine eigene Umgebung. Verweise auf lexikalische Variablen werden in einer lexikalischen Umgebung usw. aufgelöst. Mehr als eine Umgebung kann mit derselben Referenz verbunden werden. Zum Beispiel können dank der Rekursion oder der Verwendung mehrerer Threads mehrere Aktivierungen derselben Funktion gleichzeitig vorhanden sein. Diese Aktivierungen haben den gleichen Programmtext, aber jeder hat eine eigene lexikalische Umgebungsinstanz.
Um zu verstehen, worauf ein Symbol bezieht, muss der gemeinsame LISP-Programmierer wissen, welche Art von Referenz ausgedrückt wird, welche Art von Umfang er verwendet, wenn es sich um eine variable Referenz (dynamisch versus lexikaler Bereich) und auch in der Laufzeitsituation: in Welche Umgebung ist die Referenz aufgelöst, wo wurde die in die Umgebung eingeführte Bindung und Cetera eingeführt.
Arten der Umgebung
Global
Einige Umgebungen in Lisp sind weltweit allgegenwärtig. Wenn beispielsweise ein neuer Typ definiert ist, ist er danach überall bekannt. Verweise auf diesen Typ sehen sich in diesem globalen Umfeld nach.
Dynamisch
Eine Art von Umgebung in gemeinsamem Lisp ist die dynamische Umgebung. In dieser Umgebung festgelegte Bindungen haben ein dynamisches Ausmaß, was bedeutet, dass zu Beginn der Ausführung eines Konstrukts eine Bindung festgelegt wird, wie z. Lassen
Block und verschwindet, wenn das Konstrukt ausführt: Die Lebensdauer ist an die dynamische Aktivierung und Deaktivierung eines Blocks gebunden. Eine dynamische Bindung ist jedoch nicht nur in diesem Block sichtbar. Es ist auch für alle Funktionen sichtbar, die aus diesem Block aufgerufen werden. Diese Art der Sichtbarkeit wird als unbestimmter Umfang bezeichnet. Bindungen, die ein dynamisches Ausmaß (Lebensdauer an die Aktivierung und Deaktivierung eines Blocks gebunden sind) und unbestimmter Umfang (sichtbar für alle Funktionen, die aus diesem Block genannt werden) aufweisen, haben einen dynamischen Bereich.
Common LISP unterstützt dynamisch Scoped -Variablen, die auch als spezielle Variablen bezeichnet werden. Bestimmte andere Arten von Bindungen werden notwendigerweise auch dynamisch abgeschafft, z. B. Neustarts und Fang -Tags. Funktionsbindungen können nicht dynamisch mit Verwendung gesendet werden flet
(die nur lexikalisch Scoped-Funktionsbindungen liefert), aber Funktionsobjekte (ein Objekt in gemeinsamer LISP erster Ebene) können dynamisch Scoped-Variablen zugeordnet werden, die gebunden sind Lassen
in dynamischem Bereich, dann mit Verwendung aufgerufen Funcall
oder ANWENDEN
.
Der dynamische Umfang ist äußerst nützlich, da er referenzielle Klarheit und Disziplin hinzugefügt wird globale Variablen. Globale Variablen werden in der Informatik als potenzielle Fehlerquellen verpönt, da sie zu ad-hoc-verdeckten Kommunikationskanälen zwischen Modulen führen können, die zu unerwünschten, überraschenden Interaktionen führen.
In gemeinsamer LISP verhält sich eine spezielle Variable, die nur eine Bindung auf höchster Ebene aufweist, genau wie eine globale Variable in anderen Programmiersprachen. Ein neuer Wert kann darin gespeichert werden, und dieser Wert ersetzt einfach das, was sich in der obersten Bindung befindet. Der unachtsame Ersatz des Wertes einer globalen Variablen steht im Mittelpunkt der Fehler, die durch die Verwendung globaler Variablen verursacht werden. Eine andere Möglichkeit, mit einer speziellen Variablen zu arbeiten, besteht jedoch darin, ihm eine neue lokale Bindung innerhalb eines Ausdrucks zu verleihen. Dies wird manchmal als "Wiederherstellung" der Variablen bezeichnet. Das Binden einer dynamisch abgeschotteten Variablen erstellt vorübergehend einen neuen Speicherort für diese Variable und assoziiert den Namen mit diesem Ort. Während diese Bindung wirksam ist, beziehen sich alle Verweise auf diese Variable auf die neue Bindung. Die vorherige Bindung ist versteckt. Wenn die Ausführung der Bindungsexpression endet, ist der temporäre Speicherort verschwunden und die alte Bindung wird mit intakten ursprünglichen Wert aufgedeckt. Natürlich können mehrere dynamische Bindungen für dieselbe Variable verschachtelt werden.
Bei gemeinsamen LISP -Implementierungen, die Multithreading unterstützen, sind dynamische Bereiche spezifisch für jeden Ausführungsthread. Somit dienen spezielle Variablen als Abstraktion für den lokalen Speicher der Fadenspeicher. Wenn ein Thread eine spezielle Variable wiederherstellt, hat diese Wiedergebäude in anderen Threads keinen Einfluss auf diese Variable. Der in einer Bindung gespeicherte Wert kann nur durch den Thread abgerufen werden, der diese Bindung erzeugt. Wenn jeder Thread eine spezielle Variable bindet *x*
, dann *x*
verhält sich wie Thread-lokaler Speicher. Unter den Themen, die nicht wieder auftreten *x*
, es verhält es sich wie ein gewöhnlicher globaler Global: Alle diese Themen beziehen sich auf die gleiche Bindung der obersten Ebene von *x*
.
Dynamische Variablen können verwendet werden, um den Ausführungskontext mit zusätzlichen Kontextinformationen zu erweitern, die implizit von der Funktion zur Funktion übergeben werden, ohne als zusätzliche Funktionsparameter angezeigt zu werden. Dies ist besonders nützlich, wenn die Steuertransfer durch Schichten von nicht verwandtem Code geleitet werden muss, die einfach nicht mit zusätzlichen Parametern erweitert werden können, um die zusätzlichen Daten zu übergeben. Eine Situation wie diese erfordert normalerweise eine globale Variable. Diese globale Variable muss gespeichert und wiederhergestellt werden, so dass das Schema nicht unter Rekursion durchbricht: Dynamische Variable -Wiederherstellung kümmert sich darum. Und diese Variable muss Thread-lokal gemacht werden (oder es muss ein großes Mutex verwendet werden), sodass das Schema nicht unter Threads unterbricht: Dynamische Umfangsimplementierungen können sich auch darum kümmern.
In der gemeinsamen LiSP -Bibliothek gibt es viele Standard -Spezialvariablen. Beispielsweise werden alle Standard-E/A-Streams in den obersten Bindungen bekannter spezieller Variablen gespeichert. Der Standardausgangsstrom wird in *Standard-Output *gespeichert.
Nehmen wir an, eine Funktion, die Foo in die Standardausgabe schreibt:
(Defun Foo () (Format t "Hallo Welt"))
Um seine Ausgabe in einer Zeichenzeichenfolge zu erfassen, kann * Standardausgabe * an einen String-Stream gebunden und aufgerufen werden:
(mit Ausgabe zu Sait (*Standard-Ausgabe*) (Foo))
-> "Hallo, Welt"; gesammelte Ausgabe als Zeichenfolge zurückgegeben
Lexikalisch
Common Lisp unterstützt lexikalische Umgebungen. Formal haben die Bindungen in einer lexikalischen Umgebung lexikalischer Bereich und kann je nach Art des Namespace entweder ein unbestimmte Zeit oder dynamische Ausdehnung haben. Lexikalischer Bereich bedeutet, dass die Sichtbarkeit physisch auf den Block beschränkt ist, in dem die Bindung hergestellt wird. Referenzen, die nicht textuell (d. H. Lexikalisch) in diesem Block eingebettet sind, sehen diese Bindung einfach nicht.
Die Tags in einem Tagbody haben einen lexikalischen Bereich. Der Ausdruck (Go X) ist fehlerhaft, wenn er nicht in einen Tagbody eingebettet ist, der ein Etikett X enthält. Die Etikettenbindungen verschwinden jedoch, wenn der Tagbody seine Ausführung beendet, da sie dynamisches Ausmaß haben. Wenn dieser Codeblock durch die Aufruf von a wieder eingegeben wird lexikalische SchließungEs ist ungültig, dass der Körper dieses Verschlusses versucht, die Kontrolle über GO auf ein Tag zu übertragen:
(Defvar *verstorben*) ;; wird eine Funktion halten (Tagbody (setf *verstorben* (Lambda () (gehen Ein bisschen Label))) (gehen Endlabel) ;; Überspringen Sie die (drucken "Hallo") Ein bisschen Label (drucken "Hallo") Endlabel) -> NULL
Wenn der Tagbody ausgeführt wird, wird zunächst das SETF -Formular bewertet, das eine Funktion in der speziellen Variablen *abgesteckt *speichert. Dann überträgt die (go end-label) die Steuerung in das Endmarke und überspringen Sie den Code (drucken "Hallo"). Da das Endlabel am Ende des Tagbodys steht, endet der Tagbody, der NIL ergibt. Angenommen, die zuvor erinnerte Funktion heißt jetzt:
(Funcall *verstorben*) ;; Fehler!
Diese Situation ist fehlerhaft. Die Antwort einer Implementierung ist eine Fehlerbedingung, die die Nachricht "Go: Tagbody für Tag SOMELE-LABEL hat bereits übrig" enthält. Die Funktion versuchte zu bewerten (go seltsamer), das lexikalisch in den Tagbody eingebettet ist und auf das Etikett auflöst. Der Tagbody wird jedoch nicht ausgeführt (sein Ausmaß ist beendet), und so kann die Steuerentransfer nicht stattfinden.
Lokale Funktionsbindungen in LISP haben lexikalischer Bereichund variable Bindungen haben standardmäßig auch den lexikalischen Bereich. Im Gegensatz zu GO -Etiketten haben beide eine unbestimmte Zeit. Wenn eine lexikalische Funktion oder eine variable Bindung hergestellt wird, existiert diese Bindung weiterhin so lange, wie auf sie möglich ist, selbst nachdem das Konstrukt festgestellt wurde, dass die Bindung beendet ist. Verweise auf lexikalische Variablen und Funktionen nach Beendigung ihres Erstellungskonstrukts sind dank der Beendigung des Konstrukts möglich lexikalische Schließungen.
Die lexikalische Bindung ist der Standardbindungsmodus für gemeinsame LISP -Variablen. Für ein individuelles Symbol kann es entweder durch eine lokale Erklärung durch eine globale Erklärung auf dynamische Umfang umgestellt werden. Letzteres kann implizit durch die Verwendung eines Konstrukts wie Defvar oder Defparameter auftreten. Es ist eine wichtige Konvention in der gemeinsamen LISP -Programmierung, dass spezielle (d. H. Dynamisch gesellte) Variablen Namen haben, die mit einem Sternchen beginnen und enden Sigil *
in dem genannt "" "Ohrenschützer Konvention".[17] Wenn diese Konvention eingehalten wird, erstellt diese Konvention effektiv einen separaten Namespace für spezielle Variablen, sodass Variablen, die Lexikalie sind, nicht versehentlich speziell gemacht werden.
Lexikalischer Bereich ist aus mehreren Gründen nützlich.
Erstens können Verweise auf Variablen und Funktionen mit effizientem Maschinencode kompiliert werden, da die Umgebungsstruktur für die Laufzeit relativ einfach ist. In vielen Fällen kann es optimiert werden, dass die Speicherung stapelt, sodass das Öffnen und Schließen von Lexikalatomälen minimaler Overheads aufweist. Selbst in Fällen, in denen vollständige Schließungen erzeugt werden müssen, ist der Zugang zur Umgebung des Verschlusses immer noch effizient. Typischerweise wird jede Variable zu einem Versatz in einen Bindungsvektor, und so wird eine variable Referenz zu einer einfachen Last- oder Speichernanweisung mit einem Basis-Plus-Offset Adressierungsmodus.
Zweiten lexikalische Schließung, was wiederum ein ganzes Paradigma der Programmierung erzeugt, das sich auf die Verwendung von Funktionen konzentriert, die erstklassige Objekte sind, die sich an der Wurzel der funktionalen Programmierung befinden.
Drittens, vielleicht am wichtigsten, selbst wenn keine lexikalischen Verschlüsse ausgebeutet werden, die Verwendung von Programmmodulen für lexikalische Bereiche isoliert aus unerwünschten Wechselwirkungen. Aufgrund ihrer eingeschränkten Sichtbarkeit sind lexikalische Variablen privat. Wenn ein Modul A eine lexikalische Variable x bindet und ein anderes Modul B aufruft, wird Verweise auf X in B nicht versehentlich auf das in A gebundene X auflösen Wünschenswerte, gemeinsame LISP liefert spezielle Variablen. Spezielle Variablen ermöglichen ein Modul A, eine Bindung für eine Variable x einzustellen, die für ein anderes Modul B sichtbar ist, das von A genannt wird. Dies ist ein Vorteil, und es ist auch ein Vorteil, es zu verhindern, dass dies verhindern kann. Folglich unterstützt gemeinsamer Lisp sowohl lexikalische als auch dynamischer Bereich.
Makros
A Makro In Lisp ähnelt oberflächlich einer Funktion in der Verwendung. Anstatt jedoch einen Ausdruck darzustellen, der bewertet wird, stellt er jedoch eine Transformation des Programmquellcodes dar. Das Makro erhält die Quelle, die es als Argumente umgibt, bindet sie an seine Parameter und berechnet eine neue Quellform. Dieses neue Formular kann auch ein Makro verwenden. Die Makroerweiterung wird wiederholt, bis das neue Quellformular kein Makro verwendet. Das endgültige berechnete Formular ist der Quellcode, der zur Laufzeit ausgeführt wird.
Typische Verwendungen von Makros in LISP:
- Neue Kontrollstrukturen (Beispiel: Schleifenkonstrukte, Verzweigungskonstrukte)
- Scoping- und Bindungskonstrukte
- vereinfachte Syntax für komplexen und wiederholten Quellcode
- Definieren von Formularen auf oberster Ebene mit Nebenwirkungen der Kompilierzeit
- datengesteuerte Programmierung
- Eingebettete domänenspezifische Sprachen (Beispiele: Sql, Html, Prolog)
- implizite Abschlussformen
Es müssen auch verschiedene übliche LISP -Funktionen als Makros implementiert werden, wie z. B.:
- Der Standard
setf
Abstraktion, um benutzerdefinierte Kompilierungszeiten von Zuordnung/Zugriffsbetreibern zu ermöglichen -
mit Zuern
,mit Slots
,mit geöffneter Datei
und andere ähnlicheMIT
Makros - Abhängig von der Implementierung,
wenn
oderKond
ist ein Makro, das auf dem anderen, dem Spezialbetreiber, aufgebaut ist;Wenn
undwenn nicht
bestehen aus Makros - Die Mächtigen
Schleife
Domänenspezifische Sprache
Makros werden durch die definiert Defmacro Makro. Der Spezialbetreiber Makrolet Ermöglicht die Definition von lokalen (lexikalisch abgelösten) Makros. Es ist auch möglich, Makros für Symbole mithilfe von Symbolen zu definieren Symbol-Makro definieren und Symbol-Makrolet.
Paul Graham's Buch Auf Lisp beschreibt die Verwendung von Makros im Detail im gemeinsamen Lisp. Doug Hoyte's Book Over Lambda erweitert die Diskussion über Makros und behauptet, "Makros sind der größte Vorteil, den Lisp als Programmiersprache und der größte Vorteil einer Programmiersprache hat." Hoyte liefert mehrere Beispiele für die iterative Entwicklung von Makros.
Beispiel Verwenden eines Makros, um eine neue Kontrollstruktur zu definieren
Mit Makros können Lisp -Programmierer neue syntaktische Formen in der Sprache erstellen. Eine typische Verwendung besteht darin, neue Kontrollstrukturen zu erstellen. Das Beispiel -Makro liefert eine bis um
Schleifenkonstrukt. Die Syntax ist:
(bis Testform*)
Die Makrodefinition für bis um:
(Defmacro bis um (Prüfung &Karosserie Karosserie) (Lassen ((Start-Tag (Gensym "ANFANG")) (End-Tag (Gensym "ENDE"))) `(Tagbody ,Start-Tag (Wenn ,Prüfung (gehen ,End-Tag)) (Progn @Karosserie) (gehen ,Start-Tag) ,End-Tag)))
Tagbody ist ein primitiver gemeinsamer LISP -Spezialoperator, der die Möglichkeit bietet, Tags zu benennen und die zu verwenden gehen Form, um zu diesen Tags zu springen. Die Rückquote ` Bietet eine Notation, die Codevorlagen liefert, wobei der Wert von Formen, denen ein Komma vorangestellt wird gespleißt In. Der Tagbody -Formular testet die Endbedingung. Wenn die Bedingung wahr ist, springt sie zum Endetikett. Andernfalls wird der bereitgestellte Körpercode ausgeführt und springt dann zum Start -Tag.
Ein Beispiel für die Verwendung der oben genannten bis um Makro:
(bis um (= (zufällig 10) 0) (Schreiblinie "Hallo"))
Der Code kann mit der Funktion erweitert werden MACROEXPAND-1. Die Erweiterung für das obige Beispiel sieht Folgendes aus:
(Tagbody #: Start1136 (WENN (Nulle (ZUFÄLLIG 10)) (GEHEN #: End1137)) (Progn (Schreiblinie "hallo")) (GEHEN #: Start1136) #: End1137)
Während der Makroerweiterung der Wert der Variablen Prüfung ist (= (zufällig 10) 0) und der Wert der Variablen Karosserie ist ((Schreibzeile "Hallo"))). Der Körper ist eine Liste von Formularen.
Symbole werden normalerweise automatisch belastet. Die Erweiterung verwendet den Tagbody mit zwei Etiketten. Die Symbole für diese Etiketten werden von Gensym berechnet und in keinem Paket interniert. Zwei gehen Formulare verwenden diese Tags, um zu springen. Seit Tagbody ist ein primitiver Operator in gemeinsamen Lisp (und nicht ein Makro), es wird nicht in etwas anderes erweitert. Die erweiterte Form verwendet die Wenn Makro, das ebenfalls erweitert wird. Eine Quellenform vollständig erweitern wird genannt Code laufen.
In der voll erweiterten (ging) bilde die Wenn Form wird durch die Primitiven ersetzt wenn:
(Tagbody #: Start1136 (WENN (Nulle (ZUFÄLLIG 10)) (Progn (GEHEN #: End1137)) NULL) (Progn (Schreiblinie "hallo")) (GEHEN #: Start1136)) #: End1137)
Alle Makros müssen erweitert werden, bevor der Quellcode, der sie enthält, ausgewertet oder normal kompiliert werden kann. Makros können als Funktionen betrachtet werden, die akzeptieren und zurückkehren S-Expressionen - ähnlich zu Abstrakte Syntaxbäume, aber nicht beschränkt auf diese. Diese Funktionen werden vor dem Evaluator oder Compiler aufgerufen, um den endgültigen Quellcode zu erstellen. Makros sind in normalem gemeinsamem LISP geschrieben und können jeden verfügbaren Lisp (oder Drittanbieter) erhältlich sind.
Variable Erfassung und Schatten
Gemeinsame Lisp -Makros sind in der Lage, was allgemein genannt wird Variable Erfassung, wo Symbole im Makroexpansionskörper mit denen im aufrufenden Kontext übereinstimmen, sodass der Programmierer Makros erstellen kann, wobei verschiedene Symbole eine besondere Bedeutung haben. Der Begriff Variable Erfassung ist etwas irreführend, da alle Namespaces für unerwünschte Erfassung anfällig sind, einschließlich des Operator- und Funktionsnamespace, des Tagbody -Label -Namespace-, Catch -Tag-, Bedingungs -Handlers und Neustart -Namespaces.
Variable Erfassung kann Softwarefehler einführen. Dies geschieht auf eine der folgenden zwei Arten:
- In erster Linie kann eine Makroerweiterung versehentlich eine symbolische Referenz ergeben, die der Makroautor angenommen hat, wird in einem globalen Namespace auflösen, aber der Code, in dem das Makro erweitert wird, liefert zufällig eine lokale, beschattete Definition, die diese Referenz stiehlt. Lassen Sie dies als Erfassung vom Typ 1 bezeichnet.
- Der zweite Weg, Typ 2 Capture, ist genau das Gegenteil: Einige der Argumente des Makros sind Codestücke, die vom Makroaufrufer geliefert werden, und diese Code -Teile werden so geschrieben, dass sie Verweise auf umgebende Bindungen geben. Das Makro fügt diese Code -Teile jedoch in eine Erweiterung ein, die seine eigenen Bindungen definiert, die versehentlich einige dieser Referenzen erfassen.
Der Schema-Dialekt von LISP bietet ein Makroschreibsystem, das die Referenztransparenz bietet, die beide Arten von Erfassungsproblemen beseitigt. Diese Art von Makrosystem wird manchmal als "hygienisch" bezeichnet, insbesondere von seinen Befürwortern (die Makrosysteme betrachten, die dieses Problem nicht automatisch als unhygienisch lösen).
In gemeinsamer LISP wird die Makrohygiene von zwei verschiedenen Arten sichergestellt.
Ein Ansatz besteht darin, Gensyms zu verwenden: garantierte Symbole, die in einer Makroexpansion ohne Gefangennahme verwendet werden können. Die Verwendung von Gensyms in einer Makrodefinition ist eine manuelle Aufgabe, aber Makros können geschrieben werden, die die Instanziierung und Verwendung von Gensyms vereinfachen. Gensyms lösen die Typ -2 -Erfassung leicht, sie sind jedoch nicht auf die gleiche Weise für Typ -1 -Erfassungen anwendbar, da die Makroerweiterung die störenden Symbole in dem umgebenden Code, der ihre Referenzen erfasst, nicht umbenennen kann. Gensyms könnten verwendet werden, um stabile Aliase für die globalen Symbole bereitzustellen, die die Makroausdehnung benötigt. Die Makroerweiterung würde diese geheimen Aliase eher als die bekannten Namen verwenden, sodass die Neudefinition der bekannten Namen keinen schlechten Einfluss auf das Makro hat.
Ein weiterer Ansatz ist die Verwendung von Paketen. Ein in seinem eigener Paket definierter Makro kann in seiner Erweiterung einfach interne Symbole in diesem Paket verwenden. Die Verwendung von Paketen befasst sich mit der Erfassung vom Typ 1 und dem Typ 2.
Pakete lösen jedoch nicht die Erfassung von Referenzen vom Typ 1 auf Standard -LISP -Funktionen und -operatoren. Der Grund dafür ist, dass sich die Verwendung von Paketen zur Lösung von Erfassungsproblemen um die Verwendung privater Symbole dreht (Symbole in einem Paket, die nicht in andere Pakete sichtbar sind oder auf andere Weise sichtbar gemacht werden). Während die gemeinsamen Lisp-Bibliotheksymbole extern sind und häufig in benutzerdefinierte Pakete in importiert oder sichtbar werden.
Das Folgende ist ein Beispiel für unerwünschte Erfassungen im Namespace des Bedienungsbetriebs, der bei der Ausdehnung eines Makros auftritt:
;; Erweiterung von bis zur liberalen Verwendung von Do (Defmacro bis um (Ausdruck &Karosserie Karosserie) `(tun () (,Ausdruck) @Karosserie)) ;; Makrolet stellt die bindende Lexikaloperator für Do fest (Makrolet ((tun (...) ... etwas anders ...)) (bis um (= (zufällig 10) 0) (Schreiblinie "Hallo")))
Das bis um
Makro wird zu einem Formular erweitert, das aufruft tun
Dies soll sich auf das Standard -Common LISP -Makro beziehen tun
. In diesem Zusammenhang, jedoch, tun
kann eine völlig andere Bedeutung haben, also bis um
kann nicht richtig funktionieren.
Common Lisp löst das Problem der Schattierung von Standardbetreibern und Funktionen, indem sie ihre Neudefinition verbieten. Weil es den Standardbetreiber neu definiert tun
Das vorhergehende ist eigentlich ein Fragment von nicht konformen gemeinsamem Lisp, das es Implementierungen ermöglicht, sie zu diagnostizieren und abzulehnen.
Bedingungensystem
Das Bedingungensystem ist verantwortlich für Ausnahmebehandlung in gemeinsamer Lisp.[18] Es bietet Bedingungen, Handlers und neu startens. BedingungS sind Objekte, die eine außergewöhnliche Situation beschreiben (z. B. einen Fehler). Wenn ein Bedingung wird signalisiert, das gemeinsame Lisp -System sucht nach a Handler für diesen Zustandstyp und ruft den Handler auf. Das Handler Kann nun nach Neustarts suchen und einen dieser Neustarts verwenden, um das aktuelle Problem automatisch zu reparieren, indem sie Informationen wie den Bedingertyp und alle relevanten Informationen als Teil des Zustandsobjekts verwenden, und die entsprechende Neustartfunktion aufrufen.
Diese Neustarts können, wenn sie nach Code nicht behandelt werden, den Benutzern (zum Beispiel als Teil einer Benutzeroberfläche, so dass der Benutzer einen der verfügbaren Neustarts auswählen und aufrufen kann. Da der Zustandshandler im Kontext des Fehlers aufgerufen wird (ohne den Stapel abzuwickeln), ist in vielen Fällen eine vollständige Fehlerwiederherstellung möglich, wenn andere Ausnahmebehandlungssysteme die aktuelle Routine bereits beendet hätten. Der Debugger selbst kann auch mit dem angepasst oder ersetzt werden *Debugger-Hook*
Dynamische Variable. Code innerhalb Entspannungsschutz Formulare wie Finalizer werden trotz der Ausnahme ebenfalls nach angemessen ausgeführt.
Im folgenden Beispiel (mit Verwendung Symbolikgattungen) Der Benutzer versucht, eine Datei in einer Lisp -Funktion zu öffnen Prüfung aus der Read-Eval-Print-Schleife (Wiederholung), wenn die Datei nicht existiert. Das Lisp -System präsentiert vier Neustarts. Der Benutzer wählt die aus Wiederieren Sie mit einem anderen Pfadname wieder auf Starten Sie neu und treten Sie einen anderen Pfadnamen ein (Lispm-init.lisp anstelle von Lispm-int.lisp). Der Benutzercode enthält keinen Fehlerbehandlungscode. Der gesamte Fehlerbehandlungscode und der Neustartcode werden vom LiSP -System bereitgestellt, mit dem der Fehler verarbeitet und repariert werden kann, ohne den Benutzercode zu beenden.
Befehl: (Test "> Zippy> Lispm-int.lisp") Fehler: Die Datei wurde nicht gefunden. Für Lispm:> Zippy> Lispm-int.lisp.Newest LMFS: Open-Local-1 Arg 0: #P "Lispm:> Zippy> Lispm-int.lisp.Newest" S-A, <Resume> LISPM:> Zippy> Lispm-int.lisp.Newest S-B: Wiederholen Sie dies mit einem anderen Pathname S-C, <Abret>: Kehren Was für einen Pfadname stattdessen [Standard Lispm:> Zippy> Lispm-int.lisp.Newest]: Lispm:> Zippy> Lispm-init.lisp.Newest ... Das Programm geht weiter
Gemeinsames Lisp -Objektsystem (CLOS)
Common Lisp beinhaltet ein Toolkit für Objekt orientierte Programmierung, das gemeinsame Lisp -Objektsystem oder Schloss. Peter Norvig erklärt wie viele Designmuster sind einfacher zu implementieren in einer dynamischen Sprache mit den Merkmalen von CLOS (Mehrfachvererbung, Mixins, Multimethods, Metaklassen, Methodenkombinationen usw.).[19] Es wurde vorgeschlagen, dass mehrere Erweiterungen zum gemeinsamen LISP für objektorientierte Programmierung in den ANSI Common LISP-Standard einbezogen werden, aber schließlich wurde CLOS als Standard-Objektsystem für gemeinsames LISP übernommen. Clos ist a dynamisch Objektsystem mit Mehrfachversand und Mehrfacherbeund unterscheidet sich radikal von den OOP -Einrichtungen in statischen Sprachen wie z. C ++ oder Java. Als dynamisches Objektsystem ermöglicht CLOS Änderungen zur Laufzeit zu generischen Funktionen und Klassen. Methoden können hinzugefügt und entfernt werden, Klassen können hinzugefügt und neu definiert werden, Objekte können für Klassenänderungen aktualisiert und die Klasse der Objekte geändert werden.
CLOS wurde in ANSI Common LISP integriert. Generische Funktionen können wie normale Funktionen verwendet werden und sind ein erstklassiger Datentyp. Jede CLOS -Klasse ist in das gemeinsame LISP -Typ -System integriert. Viele gängige Lisp -Typen haben eine entsprechende Klasse. Es gibt mehr potenzielle Verwendung von CLOS für gemeinsames Lisp. In der Spezifikation heißt es nicht, ob die Bedingungen mit CLOS implementiert werden. Pathnames und Streams könnten mit CLOS implementiert werden. Diese weiteren Verwendungsmöglichkeiten von CLOS für ANSI Common Lisp sind nicht Teil des Standards. Tatsächliche gemeinsame LISP -Implementierungen verwenden CLOs für Pathnames, Streams, Eingabe -Output, Bedingungen, die Implementierung von Clos selbst und mehr.
Compiler und Dolmetscher
Ein LISP-Interpreter führt den LISP-Quellcode direkt aus, der als LiSP-Objekte (Listen, Symbole, Zahlen, ...) aus S-Expressions gelesen wird. Ein Lisp -Compiler erzeugt Bytecode oder Maschinensprache aus Lisp -Quellcode. Mit Common Lisp ermöglicht es sowohl einzelne LISP -Funktionen im Speicher als auch die Zusammenstellung ganzer Dateien für extern gespeichertes kompiliertes Code (Fasl Dateien).
Mehrere Implementierungen früherer Lisp -Dialekte lieferten sowohl einen Dolmetscher als auch einen Compiler. Leider waren die Semantik oft unterschiedlich. Diese früheren LISPs implementierten lexikalische Scops im Compiler und dynamischen Scoping im Dolmetscher. Common Lisp erfordert, dass sowohl der Dolmetscher als auch der Compiler standardmäßig den lexikalischen Scoping verwenden. Der gemeinsame LISP -Standard beschreibt sowohl die Semantik des Dolmetschers als auch einen Compiler. Der Compiler kann mit der Funktion aufgerufen werden kompilieren Für individuelle Funktionen und die Funktion der Funktion Datei compile für Dateien. Common Lisp ermöglicht Typdeklarationen und bietet Möglichkeiten, die Richtlinien für die Erzeugung der Compiler -Code zu beeinflussen. Für letztere können verschiedene Optimierungsqualitäten zwischen 0 (nicht wichtig) und 3 (am wichtigsten) Werte gegeben werden: Geschwindigkeit, Platz, Sicherheit, debuggen und Kompilierungsgeschwindigkeit.
Es gibt auch eine Funktion, um den LISP -Code zu bewerten: bewerten
. bewerten
Nimmt Code als vorgeschriebene S-Expressions und nicht wie in einigen anderen Sprachen als Textzeichenfolgen. Auf diese Weise kann Code mit den üblichen LISP -Funktionen für die Erstellung von Listen und Symbolen konstruiert werden, und dann kann dieser Code mit der Funktion bewertet werden bewerten
. Mehrere gemeinsame LiSP -Implementierungen (wie Clozure CL und SBCL) implementieren bewerten
mit ihrem Compiler. Auf diese Weise wird der Code kompiliert, obwohl er mit der Funktion bewertet wird bewerten
.
Der Dateikompiler wird mit der Funktion aufgerufen Datei compile. Die generierte Datei mit kompilierten Code wird a genannt Fasl (aus Schnelle Last) Datei. Diese Fasl Dateien und auch Quellcodedateien können mit der Funktion geladen werden Belastung in ein laufendes gemeinsames Lisp -System. Abhängig von der Implementierung generiert der Dateikompiler Byte-Code (zum Beispiel für die Java virtuelle Maschine), C Sprache Code (der dann mit einem C -Compiler kompiliert wird) oder direkt natives Code.
Gemeinsame LISP -Implementierungen können interaktiv verwendet werden, obwohl der Code vollständig zusammengestellt wird. Die Idee eines Interpretierte Sprache Daher gilt nicht für interaktives gemeinsames Lisp.
Die Sprache unterscheidet zwischen Lesezeit, Kompilierungszeit, Ladezeit und Laufzeit und ermöglicht den Benutzercode, dass diese Unterscheidung auch die gewünschte Art der Verarbeitung beim gewünschten Schritt durchführen kann.
Einige spezielle Betreiber werden besonders für die interaktive Entwicklung angeboten. zum Beispiel, Defvar
weist seiner bereitgestellten Variablen nur einen Wert zu, wenn er nicht bereits gebunden war Defparameter
wird immer die Aufgabe ausführen. Diese Unterscheidung ist nützlich, wenn Code in einem Live -Bild interaktiv bewertet, zusammengestellt und geladen wird.
Einige Funktionen werden auch bereitgestellt, um Compiler und Dolmetscher zu schreiben. Symbole bestehen aus Objekten der ersten Ebene und sind direkt nach Benutzercode manipulierbar. Das Progv
Der spezielle Operator ermöglicht es programmgesteuert, lexikalische Bindungen zu erstellen, während Pakete auch manipulierbar sind. Der Lisp -Compiler ist zur Laufzeit verfügbar, um Dateien oder einzelne Funktionen zu kompilieren. Diese machen es einfach, Lisp als Zwischen Compiler oder Interpreter für eine andere Sprache zu verwenden.
Codebeispiele
Geburtstagsparadox
Das folgende Programm berechnet die geringste Anzahl von Personen in einem Raum, für den die Wahrscheinlichkeit einzigartiger Geburtstage weniger als 50% beträgt (die Geburtstagsparadox, wo für 1 Person die Wahrscheinlichkeit offensichtlich 100%ist, für 2 ist sie 364/365 usw.). Die Antwort ist 23.
Nach Konvention sind Konstanten in gemeinsamer LISP mit + Zeichen eingeschlossen.
(Defconstant +Jahresgröße+ 365) (Defun Geburtstagsparadox (Wahrscheinlichkeit Anzahl der Personen) (Lassen ((Neuverhältnis (* (/ (- +Jahresgröße+ Anzahl der Personen) +Jahresgröße+) Wahrscheinlichkeit))) (wenn (< Neuverhältnis 0,5) (1+ Anzahl der Personen) (Geburtstagsparadox Neuverhältnis (1+ Anzahl der Personen)))))
Aufrufen der Beispielfunktion mit der Wiederholung (Read Eval Print Loop):
Cl-User> (Geburtstagsparadox 1.0 1) 23
Sortieren einer Liste von Personenobjekten
Wir definieren eine Klasse Person
und eine Methode zum Anzeigen des Namens und des Alters einer Person. Als nächstes definieren wir eine Gruppe von Personen als eine Liste von Person
Objekte. Dann iterieren wir über die sortierte Liste.
(Defklasse Person () ((Name : initarg :Name : Accessor Name der Person) (das Alter : initarg :das Alter : Accessor Persönlichkeit)) (:Dokumentation "Die Klassenperson mit Slots Namen und Alter.")) (Defmethod Anzeige ((Objekt Person) Strom) "Anmelden eines Personenobjekts mit einem Ausgabestream." (mit Slots (Name das Alter) Objekt (Format Strom "~ a (~ a)" Name das Alter))) (Defparameter *Gruppe* (aufführen (maßgeschneidert 'Person :Name "Bob" :das Alter 33) (maßgeschneidert 'Person :Name "Chris" :das Alter 16) (maßgeschneidert 'Person :Name "Asche" :das Alter 23)) "Eine Liste von Personenobjekten.") (Dolist (Person (Sortieren (Kopierliste *Gruppe*) #'> :Schlüssel #'Persönlichkeit)) (Anzeige Person *Standard-Ausgabe*) (Terpri))
Es druckt die drei Namen mit absteigendem Alter.
Bob (33) Asche (23) Chris (16)
Exponentierung durch Quadrat
Die Verwendung des Schleifenmakros wird nachgewiesen:
(Defun Energie (x n) (Schleife mit Ergebnis = 1 während (Plusp n) Wenn (ODDP n) tun (setf Ergebnis (* Ergebnis x)) tun (setf x (* x x) n (kürzen n 2)) endlich (Rückkehr Ergebnis)))
Beispiel Verwendung:
Cl-User> (Power 2 200) 1606938044258990275541962092341162602522202993782792835301376
Vergleiche mit der eingebauten Exponentiation:
Cl-User> (= (expt 2 200) (Power 2 200)) t
Suchen Sie die Liste der verfügbaren Shells
With-Open-File ist ein Makro, das eine Datei öffnet und einen Stream bereitstellt. Wenn das Formular zurückkehrt, wird die Datei automatisch geschlossen. Funcall ruft ein Funktionsobjekt auf. Die Schleife sammelt alle Zeilen, die dem Prädikat entsprechen.
(Defun Listenanpassungslinien (Datei Prädikat) "Gibt eine Liste von Zeilen in der Datei zurück, für die das Prädikat angewendet wird Die Linie gibt T. "zurück." (mit geöffneter Datei (Strom Datei) (Schleife zum Linie = (Zeile lesen Strom Null Null) während Linie Wenn (Funcall Prädikat Linie) sammeln es)))
Die verfügbaren Funktions-Shells rufen die oben genannten Funktionslisten-Matching-Linien mit einem Pfadnamen und einer anonymen Funktion als Prädikat auf. Das Prädikat gibt den Pfadnamen einer Shell oder NIL zurück (wenn die Zeichenfolge nicht der Dateiname einer Shell ist).
(Defun Verfügbare Schalen (&Optional (Datei #P "/etc/Shells")) (Listenanpassungslinien Datei (Lambda (Linie) (und (Plusp (Länge Linie)) (char = (verkohlen Linie 0) #\/) (Pfadname (String-Right-Trim '(#\Platz #\Tab) Linie))))))
Beispielergebnisse (unter Mac OS X 10.6):
Cl-User > (Verfügbare Schalen) (#P "/bin/bash" #P "/bin/csh" #P "/bin/ksh" #P "/bin/sh" #P "/bin/tcsh" #P "/bin/zsh")
Vergleich mit anderen LISPs
Common Lisp wird am häufigsten im Vergleich zu und im Gegensatz zu. Planen- Nur weil sie die beiden beliebtesten Lisp -Dialekte sind. Schema geht vor Cl und stammt nicht nur aus derselben Lisp -Tradition, sondern auch aus einigen der gleichen Ingenieure -Guy L. Steele, mit denen Gerald Jay Sussman Entworfenes Programm, leitete das Standardausschuss für Common Lisp.
Common Lisp ist eine allgemeine Programmiersprache im Gegensatz zu Lisp-Varianten wie z. EMACS Lisp und Autolisp welche sind Erweiterungssprachen Eingebettet in bestimmten Produkten (GNU EMACs bzw. Autocad). Im Gegensatz zu vielen früheren LISPs, Common Lisp (wie wie Planen) verwendet lexikalische Variable Umfang Standardmäßig für interpretierte und kompilierte Code.
Die meisten LISP -Systeme, deren Designs zu einem gemeinsamen LISP beitrugen - wie z. B. wie Zetalisp und Franz Lisp - dynamisch verwendet Scoped Variablen in ihren Dolmetschern und lexikalisch abgeschotteten Variablen in ihren Compilern. Das Schema führte die alleinige Verwendung von lexikalisch abgeschotteten Variablen in LISP ein. Eine Inspiration von Algol 68. CL unterstützt auch dynamisch abgeschottete Variablen, müssen jedoch explizit als "Spezial" deklariert werden. Es gibt keine Unterschiede in der Scoping zwischen ANSI -CL -Dolmetschern und Compilern.
Common Lisp wird manchmal als a bezeichnet Lisp-2 und Schema a Lisp-1bezieht sich auf die Verwendung von CL durch separate Namespaces für Funktionen und Variablen. (Tatsächlich hat CL viele Namespaces wie die für Go -Tags, Blocknamen und Schleife
Schlüsselwörter). Es gibt eine langjährige Kontroverse zwischen CL und System-Befürwortern über die Kompromisse, die an mehreren Namespaces beteiligt sind. Im Schema ist es (allgemein) notwendig, Variablennamen zu vermeiden, die mit Funktionen zusammenbrechen. Schemafunktionen haben häufig Argumente benannt lis
, lst
, oder lyst
Um nicht mit der Systemfunktion zu konflikt aufführen
. In CL ist es jedoch notwendig, ausdrücklich auf den Funktionsnamenspace zu verweisen, wenn sie eine Funktion als Argument übergeben - was auch ein häufiges Ereignis ist, wie in der Sortieren
Beispiel oben.
CL unterscheidet sich auch vom Schema bei der Behandlung von Booleschen Werten. Schema verwendet die speziellen Werte #T und #F, um Wahrheit und Falschheit darzustellen. CL folgt der älteren Lisp -Konvention der Verwendung der Symbole T und Nil, wobei Nil auch für die leere Liste steht. In cl, irgendein Nicht-Nil-Wert wird durch Bedingungen als wahr behandelt, wie z. wenn
, während im Schema alle Nicht-#-F-Werte als wahr behandelt werden. Diese Konventionen ermöglichen es einigen Betreibern in beiden Sprachen, sowohl als Prädikate (Beantwortung einer booleschen Frage) als auch als Rückgabe eines nützlichen Werts für die weitere Berechnung zu dienen, aber im Schema den Wert '(), was NIL in gemeinsamer LISP äquiviert, bewertet dem wahren Wert. in einem booleschen Ausdruck.
Schließlich erfordern die Dokumente der Schema -Standards Schwanzoptimierung, was der CL -Standard nicht tut. Die meisten CL-Implementierungen bieten eine Optimierung der Schwanzberechnung, jedoch häufig nur, wenn der Programmierer eine Optimierungsrichtlinie verwendet. Dennoch bevorzugt der gemeinsame CL -Codierungsstil die allgegenwärtige Verwendung von Rekursion, die der Schema -Stil bevorzugt - was ein Schemeprogrammierer mit Schwanzrekursion ausdrücken würde, ein CL -Benutzer würde normalerweise mit einem iterativen Ausdruck in ausdrücken tun
, Dolist
, Schleife
, oder (in jüngerer Zeit) mit dem iterieren
Paket.
Implementierungen
Siehe die Kategorie Common Lisp -Implementierungen.
Common Lisp wird durch eine Spezifikation definiert (wie Ada und C) und nicht durch eine Implementierung (wie wie Perl). Es gibt viele Implementierungen und die Standarddetailsbereiche, in denen sie sich gültig unterscheiden können.
Darüber hinaus sind Implementierungen in der Regel mit Erweiterungen ausgestattet, die Funktionen liefern, die nicht im Standard behandelt werden:
- Interaktive obere Ebene (Repl)
- Müllsammlung
- Debugger, Stepper und Inspektor
- Schwache Datenstrukturen (Hash -Tabellen)
- Erweiterbare Sequenzen
- Erweiterbare Schleife
- Umweltzugang
- Clos Meta-Objektprotokoll
- CLOS -basierte erweiterbare Ströme
- CLOS -basiertes Bedingungensystem
- Netzwerkströme
- Persistierender Clos
- Unicode -Unterstützung
- Fremdsprachige Schnittstelle (oft zu C)
- Betriebssystemschnittstelle
- Java -Schnittstelle
- Themen und Multiprozessing
- Anwendungsbereitstellung (Anwendungen, dynamische Bibliotheken)
- Speichern von Bildern
Kostenlose und Open-Source-Software Es wurden Bibliotheken erstellt, um Erweiterungen auf tragbare Weise zu unterstützen, und sind vor allem in den Repositories der Common-lisp.net zu finden[20] und Clocc (Common Lisp Open Code Collection)[21] Projekte.
Gemeinsame LISP -Implementierungen können jede Mischung aus natives Code -Zusammenstellung, Byte -Code -Kompilierung oder Interpretation verwenden. Common Lisp wurde entwickelt, um sie zu unterstützen Inkrementelle Compiler, Datei Compiler und Block Compiler. Standarddeklarationen zur Optimierung der Kompilierung (z. B. Funktionsinginierung oder Typspezialisierung) werden in der Sprachspezifikation vorgeschlagen. Die meisten gängigen LISP -Implementierungen kompilieren den Quellcode für native Maschinensprache. Einige Implementierungen können eigenständige Anwendungen erstellen. Andere kompilieren zu interpretiert Bytecode, was weniger effizient ist als natives Code, aber die Binärcode-Portabilität erleichtert. Einige Compiler kompilieren gemeinsames Lisp -Code zum C -Code. Das Missverständnis, dass LISP eine rein interpretierte Sprache ist, ist höchstwahrscheinlich, weil Lisp-Umgebungen eine interaktive Eingabeaufforderung darstellen und dass Code auf inkrementelle Weise einseitig zusammengestellt wird. Bei gemeinsamer Lisp -inkrementeller Zusammenstellung wird häufig verwendet.
Etwas Unix-basierte Implementierungen (Cliv, SBCL) kann als verwendet werden Skriptsprache; das heißt, das System transparent auf die Art und Weise, wie a Perl oder Unix Shell Interpreter ist.[22]
Liste der Implementierungen
Kommerzielle Implementierungen
- Allegro Common Lisp
- Für Microsoft Windows, FreeBSD, Linux, Apple MacOS und verschiedene Unix -Varianten. Allegro CL bietet eine Integrierte Entwicklungsumgebung (IDE) (für Windows und Linux) und umfangreiche Funktionen für die Bereitstellung von Anwendungen.
- Flüssiges gemeinsames Lisp
- früher genannt Lucid Common Lisp. Nur Wartung, keine neuen Veröffentlichungen.
- Lispworks
- Für Microsoft Windows, FreeBSD, Linux, Apple MacOS, iOS, Android und verschiedene Unix -Varianten. Lispworks bietet an Integrierte Entwicklungsumgebung (IDE) (Für die meisten Plattformen erhältlich, jedoch nicht für iOS und Android) und umfangreiche Funktionen für die Anwendungsbereitstellung.
- Mocl
- für iOS, Android und Macos.
- Offene Gattungen
- Für Dec Alpha.
- Scieneer Common Lisp
- Das ist für leistungsstarke wissenschaftliche Computing ausgelegt.
Freiumverteilbare Implementierungen frei
- Bewaffneter Bär Common Lisp (ABCL)
- Eine CL -Implementierung, die auf dem ausgeführt wird Java virtuelle Maschine.[23] Es enthält einen Compiler zu Java -Byte -Codeund ermöglicht den Zugriff auf Java -Bibliotheken von Cl. Es war früher nur ein Bestandteil des Herausgebers des bewaffneten Bären.
- Cliv
- Eine Bytecode-Compiling-Implementierung, tragbar und läuft auf mehreren UNIX- und UNIX-ähnlichen Systemen (einschließlich Mac OS) sowie Microsoft Windows und mehrere andere Systeme.
- Clozure Cl (CCL)
- Ursprünglich a frei und offen Gabel von Macintosh Common Lisp. Wie diese Geschichte schon sagt, wurde CCL für den Macintosh geschrieben, aber Clozure CL läuft jetzt weiter Mac OS, Freebsd, Linux, Solaris und Fenster. 32 und 64 Bit x86 Ports werden auf jeder Plattform unterstützt. Zusätzlich gibt es Strom -PC -Ports für Mac OS und Linux. CCL war zuvor als OpenMCL bekannt, aber dieser Name wird nicht mehr verwendet, um Verwirrung mit der Open -Source -Version von Macintosh Common Lisp zu vermeiden.
- Cmucl
- Ursprünglich aus Carnegie Mellon Universität, jetzt gepflegt als Kostenlose und Open-Source-Software von einer Gruppe von Freiwilligen. CMUCL verwendet einen schnellen nativen Code-Compiler. Es ist verfügbar auf Linux und BSD für Intel x86; Linux für Alpha; Mac OS für Intel x86 und powerpc; und Solaris, Irrix und HP-UX auf ihren nativen Plattformen.
- Corman Common Lisp
- Für Microsoft Windows. Im Januar 2015 wurde Corman Lisp unter MIT -Lizenz veröffentlicht.[24]
- Eingebettbares gemeinsames Lisp (ECL)
- ECL enthält einen Bytecode -Interpreter und Compiler. Es kann auch Lisp -Code zum Maschinencode über einen C -Compiler kompilieren. ECL kompiliert dann Lisp -Code nach C, kompiliert den C -Code mit einem C -Compiler und kann dann den resultierenden Maschinencode laden. Es ist auch möglich, ECL in einzubetten C Programme und C -Code in gemeinsame LISP -Programme.
- GNU Common Lisp (GCL)
- Das GNU Project Lisp Compiler. GCL ist jedoch noch nicht vollständig ansi konform, und ist jedoch die Implementierung der Wahl für mehrere große Projekte, einschließlich der mathematischen Tools Maxima, AXIOM und (historisch) ACL2. GCL läuft weiter Linux unter elf verschiedenen Architekturen und auch unter Windows, Solaris und Freebsd.
- Macintosh Common Lisp (MCL)
- Version 5.2 für Apple Macintosh -Computer mit einem PowerPC -Prozessor, der Mac OS X ausführt, ist Open Source. RMCL (basierend auf MCL 5.2) läuft auf Intel-basierten Apple Macintosh-Computern mit dem Rosetta-binären Übersetzer von Apple.
- Mankai Common Lisp (MKCL)
- Ein Zweig von ECL. MKCL betont Zuverlässigkeit, Stabilität und Gesamtcodequalität durch ein stark überarbeitetes, nativ multi-threades Laufzeitsystem. Unter Linux verfügt MKCL über ein vollständig posix -konformes Laufzeitsystem.
- Movitz
- Implementiert eine Lisp -Umgebung für x86 Computer, ohne sich auf ein zugrunde liegendes Betriebssystem zu verlassen.
- Papplog
- Poplog implementiert eine Version von CL mit Pop-11und optional Prolog, und Standard ml (SML), um eine gemischte Sprachprogrammierung zuzulassen. Für alle ist die Implementierungssprache POP-11, die inkrementell kompiliert wird. Es hat auch eine integrierte EMACs-ähnlich Editor, der mit dem Compiler kommuniziert.
- Stahlbank Common Lisp (SBCL)
- Ein Zweig von Cmucl. "Im Großen und Ganzen unterscheidet sich SBCL von der CMU CL durch eine stärkere Betonung der Wartbarkeit."[25] SBCL läuft auf den Plattformen, die CMUCL macht, außer HP/UX; Außerdem läuft es unter Linux für AMD64, PowerPC, SPARC, MIPS, Windows X86[26] und hat experimentelle Unterstützung für das Laufen unter Windows AMD64. SBCL verwendet standardmäßig keinen Dolmetscher. Alle Ausdrücke werden mit nativem Code kompiliert, es sei denn, der Benutzer schaltet den Interpreter ein. Der SBCL -Compiler generiert einen schnellen nativen Code gemäß einer früheren Version von Das Computer mit Computersprachen -Benchmarks Spiel.[27]
- Ufasoft Common Lisp
- Port of Clisp for Windows Platform mit Kern in C ++ geschrieben.
Andere Implementierungen
- Austin Kyoto Common Lisp
- eine Entwicklung von Kyoto Common Lisp durch Bill Schelter
- Butterfly Common Lisp
- eine Implementierung in Schema für die BBN Butterfly Mehrprozessor-Computer[28][29]
- Clicc
- ein gemeinsamer LISP -to C -Compiler[30]
- Cloe
- Gemeinsame Lisp für PCs von Symbolik
- Codemist Common Lisp
- Wird für die kommerzielle Version des Computer -Algebra -Systems Axiom verwendet[31][32]
- Expercommon Lisp
- Eine frühzeitige Implementierung für den Apple Macintosh durch Expertenz
- Golden Common Lisp
- Eine Implementierung für den PC von Goldhill Inc.[33][34]
- Ibuki Common Lisp
- Eine kommerzialisierte Version von Kyoto Common Lisp
- Kyoto Common Lisp
- Der erste gemeinsame Lisp -Compiler, der C als Zielsprache verwendete. GCL, ECL und MKCL stammen aus dieser gemeinsamen LISP -Implementierung.
- L
- Eine kleine Version von Common Lisp für eingebettete Systeme, die von Robotik entwickelt wurden, jetzt Irobot[35]
- Lisp -Maschinen (aus Symbolik, Ti[36][37] und Xerox[38])
- Bereitstellung von Implementierungen von gemeinsamem LISP zusätzlich zu ihrem nativen LISP -Dialekt (Lisp Machine Lisp oder Interisp). Clos war ebenfalls erhältlich. Symbolik bietet eine verbesserte Version Common Lisp.[39][40][41]
- Procyon Common Lisp
- Eine Implementierung für Windows und Mac OS, die von Franz für ihren Windows -Port von Allegro CL verwendet wird
- Star Saphir Common Lisp
- eine Implementierung für den PC
- Subl
- Eine Variante des gemeinsamen Lisp Cyc Wissensbasiertes System[42]
- Top -Level Common Lisp
- Eine frühzeitige Umsetzung für die gleichzeitige Ausführung[43]
- Wcl
- eine gemeinsame Bibliotheksimplementierung[44][45]
- Vax Common Lisp
- Digital Equipment CorporationImplementierung, die weiterlief Vax Systeme laufen VMs oder Ultrix
- Xlisp
- Eine Implementierung von David Betz[46]
Anwendungen
Common Lisp wird verwendet, um Forschungsanwendungen zu entwickeln (häufig in Künstliche Intelligenz) für die schnelle Entwicklung von Prototypen oder für bereitgestellte Anwendungen.
Common Lisp wird in vielen kommerziellen Anwendungen verwendet, einschließlich der Yahoo! Speichern Sie die Web-Commerce-Website, die ursprünglich beteiligt war Paul Graham und wurde später neu geschrieben C ++ und Perl.[47] Andere bemerkenswerte Beispiele sind:
- ACT-R, Eine kognitive Architektur, die in einer Vielzahl von Forschungsprojekten verwendet wird.
- Assistent des Autorisierers,[48][49] Ein großes regelbasiertes System von American Express, das Kreditanforderungen analysiert.
- Cyc, ein langjähriges Projekt zur Schaffung eines wissensbasierten Systems, das eine große Menge an gesunden Menschenverstandswissen vermittelt.
- Gensym G2, ein Echtzeit-Expertensystem und Business Rules Engine[50]
- GenWorks GDL,[51] Basierend auf dem Open-Source-Gendl-Kernel.
- Die Entwicklungsumgebung für die Jak und Daxter Videospielreihe, entwickelt von von Frecher Hund.
- Ita Software'S Low Tarif Search Engine, verwendet von Reisewebsites wie z. B. Orbitz und Kayak.com und Fluggesellschaften wie American Airlines, Continental Airlines und US Airways.
- Mirai, eine 3D -Graphics -Suite. Es wurde verwendet, um das Gesicht von zu animieren Gollum im Film Herr der Ringe: die beiden Türme.
- Opusmodus ist ein Musikkompositionssystem, das auf gemeinsamem Lisp basiert und in verwendet wird Computergestützte Komposition.[52]
- Prototyp -Überprüfungssystem (PVS), eine mechanisierte Umgebung für formale Spezifikation und Überprüfung.
- PWGL ist eine anspruchsvolle visuelle Programmierumgebung, die auf gemeinsamem Lisp basiert, das in verwendet wird Computergestützte Komposition und Tonsynthese.[53]
- Klavier, eine vollständige Flugzeuganalyse -Suite, geschrieben in Common Lisp,[54] verwendet von Unternehmen wie Boeing, Airbus, und Northrop Grumman.[55]
- GrammatikEine englischsprachige Schreibverbesserungsplattform hat ihre Kern-Grammatik-Engine in gemeinsamen LISP geschrieben.[56]
- Das Dynamische Analyse und Wiederholungswerkzeug (Dart), was allein in den Jahren von 1991 bis 1995 seit dreißig Jahren zurückgezahlt hat DARPA Investitionen in die KI -Forschung.
- NASA's Jet Propulsion Lab's "Deep Space 1", eine preisgekrönte[57] Common Lisp[58] Programm zur Autopilotierung der Deep Space eins Raumschiff.
- Siglab, eine gemeinsame Lisp -Plattform für die Signalverarbeitung in der Raketenverteidigung, gebaut von Raytheon.[54]
- NASAs Mars Pathfinder Missionsplanungssystem.[59]
- Spike, ein Planungssystem für Erd- oder Raumbasis -Observatorien und Satelliten, insbesondere die Hubble -Weltraumteleskop,[60] geschrieben in gemeinsam Lisp.[61]
- Common Lisp wurde zum Prototyping des Müllsammlers von Microsoft verwendet .NETZ Gemeinsame Sprachlaufzeit.[62]
- Die Originalversion von Reddit, obwohl die Entwickler später zu wechseln zu Python Laut einem offiziellen Blog-Beitrag von Reddit-Mitbegründer aufgrund des Mangels an Bibliotheken für Common LISP Steve Huffman.[63]
Es gibt auch Open-Source-Anwendungen, die in gemeinsamen LISP geschrieben wurden, z. B.:
- ACL2, ein Vollgeeignet automatisierter Theoremprover für ein Anwendung Variante des gemeinsamen Lisp.
- Axiom, eine raffinierte Computeralgebra -System.
- Maxima, eine raffinierte Computeralgebra -Systembasierend auf der Macsyma.
- OpenMusic, eine objektorientierte visuelle Programmierumgebung basierend auf gemeinsamem Lisp, verwendet in Computergestützte Komposition.
- Pgloader,[64] ein Datenlader für PostgreSQL, was von Python zu Common Lisp umgeschrieben wurde.[65]
- Stumpf, ein Fliesen, Tastaturantrieb X11 -Fenstermanager, das vollständig in gemeinsamem Lisp geschrieben wurde.
Siehe auch
Verweise
- ^ "ANSI Standards Action - 28. Dezember 2018" (PDF). Ansi.org.
- ^ Zitiert aus der Abdeckung des zitierten Standards. ANSI incits 226-1994 [S2008], zum Verkauf auf Standards Dokumentseite Archiviert 27. September 2020 bei der Wayback -Maschine.
- ^ "CLHS: Über den gemeinsamen Lispyperspec (TM)". Lispworks.com.
- ^ "CLHS: Abschnitt 1.1.2". Lispworks.com.
- ^ "Common Lisp -Implementierungen: Eine Umfrage". Archiviert von das Original am 21. April 2012. Abgerufen 22. Dezember, 2007.
- ^ "Alte LISP -Programme werden immer noch in gemeinsam lisparischem LISP ausgeführt". Abgerufen 13. Mai, 2015.
- ^ "Wurzeln von" Yu-shiang Lisp ", Mail von Jon L White, 1982". CMU.edu.
- ^ "Mail -Index". cl-su-ai.lisp.se.
- ^ Knie-Jerk-Anti-Loopismus und andere E-Mail-Phänomene: mündliche, geschriebene und elektronische Muster in computergestützter Kommunikation, Joanne Yates und Wanda J. Orlikowski., 1993 Archiviert 8. August 2012 bei der Wayback -Maschine
- ^ JR, Steele; L, Guy (15. August 1982). Ein Überblick über Common Lisp. LFP '82. ACM. S. 98–107. doi:10.1145/800068.802140. ISBN 9780897910828. S2CID 14517358.
- ^ Reddy, Abhishek (22. August 2008). "Merkmale von Common Lisp" ".
- ^ "Unicode -Unterstützung". Das gemeinsame Lisp -Wiki. Abgerufen 21. August, 2008.
- ^ Richard P. Gabriel; Kent M. Pitman (Juni 1988). "Technische Probleme der Trennung in Funktionszellen und Wertzellen". Lisp und symbolische Berechnung. 1 (1): 81–101. doi:10.1007/bf01806178. S2CID 26716515.
- ^ "Common Lisp hyperspec: Abschnitt 3.1.7".
- ^ "Common Lisp hyperspec: Funktionsboden".
- ^ "Common Lisp hyperspec: Accessor Gethash".
- ^ "Lambda überlassen". letoverlambda.com.
- ^ Peter Seibel (7. April 2005). Praktisches gemeinsames Lisp. Apress. ISBN 978-1-59059-239-7.
- ^ "Designmuster in der dynamischen Programmierung". Norvig.com.
- ^ "Common-lisp.net".
- ^ "Common Lisp Open Code Sammlung".
- ^ "32.6. QuickStarting Delivery mit Clisp". clisp.cons.org.
- ^ "Bewaffneter Bär Common Lisp".
- ^ "Corman Lisp -Quellen sind jetzt verfügbar".
- ^ "Geschichte und Urheberrecht". Stahlbank Common Lisp.
- ^ "Plattformtabelle". Stahlbank Common Lisp.
- ^ "Welche Programme sind am schnellsten? - Computer Sprach -Benchmarks -Spiel". 20. Mai 2013. archiviert von das Original am 20. Mai 2013.
- ^ "Paket: Lang/Lisp/Impl/BBN/". cs.cmu.edu.
- ^ "Jüngste Entwicklungen in Butterfly Lisp, 1987, AAAI -Verfahren" (PDF). aaai.org.
- ^ Burkart, O.; Goerigk, W.; Knuzen, H. (22. Juni 1992). "CLICC: Ein neuer Ansatz zur Zusammenstellung gemeinsamer LISP -Programme zu C". Citeseerx 10.1.1.38.1282.
{{}}
: Journal zitieren erfordert|journal=
(Hilfe) - ^ "codemist.co.uk". lisp.codemist.co.uk.
- ^ "Axiom, der 30 -jährige Horizont, Seite 43" (PDF).
- ^ "Golden Common Lisp Developer". goldhill-inc.com.
- ^ Golden Common Lisp: Ein praktischer Ansatz, David J. Steele, Juni 2000 von Addison Wesley Publishing Company
- ^ Brooks, Rodney A.; Al., ET (22. Juni 1995). "L - ein gemeinsames Lisp für eingebettete Systeme". Citeseerx 10.1.1.2.1953.
{{}}
: Journal zitieren erfordert|journal=
(Hilfe) - ^ "Ti Explorer -Programmierkonzepte" (PDF).
- ^ "Ti Explorer Lisp Referenz" (PDF).
- ^ "Medley Lisp -Versionsnotizen" (PDF).
- ^ "Symbolics Common Lisp Dictionary" (PDF). Trailing-eded.com.
- ^ "Symbolics Common Lisp -Sprachkonzepte" (PDF). Trailing-eded.com.
- ^ "Symbolics Common Lisp -Programmierkonstrukte" (PDF). Trailing-eded.com.
- ^ "Subl -Referenz - Cycorp". cyc.com.
- ^ "Top Level Inc. - Software Preservation Group". SoftwarePeservation.org.
- ^ WCL: Effiziente gemeinsame LISP -Anwendungen nach UNIX, Verfahren der ACM -Konferenz von 1992 über LISP- und Funktionsprogrammierung, Seiten 260–269
- ^ "Commonlisp.net :: Wcl". pgc.com. Archiviert von das Original am 5. April 2016. Abgerufen 25.März, 2016.
- ^ "Paket: Lang/Lisp/Impl/Xlisp/". cs.cmu.edu.
- ^ "Die Durchschnittswerte schlagen". Paulgraham.com.
- ^ "Assistent des Autorisierers" (PDF). aaai.org.
- ^ Assistent des American Express Autorizer Archiviert 12. Dezember 2009 bei der Wayback -Maschine
- ^ Echtzeit-Anwendungsentwicklung Archiviert 2. August 2016 bei der Wayback -Maschine. Gensym. Abgerufen am 16. August 2016.
- ^ "GenWorks GDL".
- ^ "Opusmodus - Zuhause".
- ^ PWGL - Zuhause Archiviert 3. Mai 2011 bei der Wayback -Maschine, Abgerufen am 17. Juli 2013.
- ^ a b "Luft- und Raumfahrt - Common Lisp". Lisp-Lang.org.
- ^ "Klavierbenutzer, abgerufen von der Herstellerseite".
- ^ "Grammarly.com, lispend in der Produktion". 26. Juni 2015.
- ^ "Remote Agent". ti.arc.nasa.gov.
- ^ "Lisping bei JPL".
- ^ "Franz Inc Customer Applications: NASA". Franz.com.
- ^ Spike -Planungs- und Planungssystem. STSCI.EDU. Abgerufen am 17. Juli 2013.
- ^ "Franz Inc Customer Applications: Space Telescope Institute". Franz.com.
- ^ "Wie alles begann ... auch bekannt als die Geburt des CLR". microsoft.com.
- ^ Huffman, Steve. "auf Lisp". Upvoted. Archiviert von das Original am 17. Mai 2018. Abgerufen 11. Mai, 2019.
- ^ "PGLOADER".
- ^ "Warum ist PGLOADER so viel schneller?".
Literaturverzeichnis
Eine chronologische Liste von Büchern, die veröffentlicht werden (oder kurz vor dem veröffentlichten) über gemeinsamen Lisp (der Sprache) oder über das Programmieren mit gemeinsamem Lisp (insbesondere AI -Programmierung).
- Guy L. Steele: Common Lisp the Language, 1. Auflage, Digital Press, 1984, ISBN0-932376-41-x
- Rodney Allen Brooks: Programmierung in gemeinsamer Lisp, John Wiley und Sons Inc, 1985,, ISBN0-471-81888-7
- Richard P. Gabriel: Leistung und Bewertung von LISP -Systemen, The MIT Press, 1985, ISBN0-262-57193-5,, PDF
- Robert Wilensky: Gemeinsames Lispcraft, W.W. Norton & Co., 1986, ISBN0-393-95544-3
- Eugene Charniak, Christopher K. Riesbeck, Drew V. McDermott, James R. Meehan: Programmierung künstlicher Intelligenz, 2. Ausgabe, Lawrence Erlbaum, 1987, ISBN0-89859-609-2
- Wendy L. Milner: Common Lisp: Ein Tutorial, Prentice Hall, 1987, ISBN0-13-152844-0
- Deborah G. Tatar: Ein Programmierhandbuch für Common Lisp, Longman Higher Education, 1987, ISBN0-13-728940-5
- Taiichi Yuasa, Masami Hagiya: Einführung in das Common Lisp, Elsevier Ltd, 1987,, ISBN0-12-774860-1
- Christian Queinnec, Jerome Chailloux: Lisp -Entwicklung und Standardisierung, IOS PR Inc., 1988, ISBN90-5199-008-1
- Taiichi Yuasa, Richard Weyhrauch, Yasuko Kitajima: Gemeinsamer Lisp -Bohrer, Academic Press Inc, 1988, ISBN0-12-774861-x
- Wade L. Hennessey: Common Lisp, McGraw-Hill Inc., 1989, ISBN0-07-028177-7
- Tony Hasemer, John Dominque: Gemeinsame Lisp -Programmierung für künstliche Intelligenz, Addison-Wesley Educational Publishers Inc, 1989, ISBN0-201-17579-7
- Sonya E. Keene: Objektorientierte Programmierung in Common Lisp: A Programmer's Leitfaden zum CLOS, Addison-Wesley, 1989, ISBN0-201-17589-4
- David Jay Steele: Golden Common Lisp: Ein praktischer Ansatz, Addison Wesley, 1989, ISBN0-201-41653-0
- David S. Touretzky: Common Lisp: Eine sanfte Einführung in die symbolische Berechnung, Benjamin-Cummings, 1989, ISBN0-8053-0492-4. Web/PDF Dover Nachdruck (2013) ISBN978-0486498201
- Christopher K. Riesbeck, Roger C. Schank: Innerhalb fallbasierter Argumentation, Lawrence Erlbaum, 1989, ISBN0-89859-767-6
- Patrick Winston, Berthold Horn: Lisp, 3. Auflage, Addison-Wesley, 1989, ISBN0-201-08319-1,, Netz
- Gerard Gazdar, Chris Mellish: Verarbeitung natürlicher Sprache in LISP: Eine Einführung in die Computer -Linguistik, Addison-Wesley Longman Publishing Co., 1990, ISBN0-201-17825-7
- Patrick R. Harrison: Gemeinsame Lisp und künstliche Intelligenz, Prentice Hall PTR, 1990, ISBN0-13-155243-0
- Timothy Koschmann: Der gemeinsame Lisp -Begleiter, John Wiley & Sons, 1990, ISBN0-471-50308-8
- W. Richard Stark: Lisp, Überlieferung und Logik, Springer Verlag New York Inc., 1990, ISBN978-0-387-97072-1, PDF
- Molly M. Miller, Eric Benson: Lisp -Stil & Design, Digital Press, 1990, ISBN1-55558-044-0
- Guy L. Steele: Gemeinsam lispeln die Sprache, 2. Auflage, Digital Press, 1990, ISBN1-55558-041-6,, Netz
- Robin Jones, Clive Maynard, Ian Stewart: Die Kunst der Lisp -Programmierung, Springer Verlag New York Inc., 1990, ISBN978-3-540-19568-9,, PDF
- Steven L. Tanimoto: Die Elemente der künstlichen Intelligenz mit gemeinsamem Lisp, Informatik Press, 1990, ISBN0-7167-8230-8
- Peter Lee: Themen in der Implementierung der erweiterten Sprache, The MIT Press, 1991, ISBN0-262-12151-4
- John H. Riley: Ein gemeinsames Lisp -Arbeitsbuch, Prentice Hall, 1991, ISBN0-13-155797-1
- Peter Norvig: Paradigmen der Programmierung künstlicher Intelligenz: Fallstudien in gemeinsamer Lisp, Morgan Kaufmann, 1991, ISBN1-55860-191-0,, Netz
- Gregor Kiczales, Jim des Rivieres, Daniel G. Bobrow: Die Kunst des MetaObject -Protokolls, The MIT Press, 1991, ISBN0-262-61074-4
- Jo A. Lawless, Molly M. Miller: Verstehen von Clos: Das gemeinsame Lisp -Objektsystem, Digital Press, 1991, ISBN0-13-717232-x
- Mark Watson: Gemeinsame Lisp -Module: Künstliche Intelligenz in der Ära der neuronalen Netzwerke und der Chaostheorie, Springer Verlag New York Inc., 1991, ISBN0-387-97614-0,, PDF
- James L. Noyes: Künstliche Intelligenz mit gemeinsamem Lisp: Grundlagen der symbolischen und numerischen Verarbeitung, Jones & Bartlett Pub, 1992, ISBN0-669-19473-5
- Stuart C. Shapiro: Common Lisp: Ein interaktiver Ansatz, Informatik Press, 1992, ISBN0-7167-8218-9,, Web/PDF
- Kenneth D. Forbus, Johan de Kleer: Problemlöser aufbauen, The MIT Press, 1993, ISBN0-262-06157-0
- Andreas Paepcke: Objektorientierte Programmierung: Die CLOS-Perspektive, The MIT Press, 1993, ISBN0-262-16136-2
- Paul Graham: Auf Lisp, Prentice Hall, 1993, ISBN0-13-030552-9,, Web/PDF
- Paul Graham: ANSI Common Lisp, Prentice Hall, 1995, ISBN0-13-370875-6
- Otto Mayer: Programmier in gemeinsamer Lisp, Deutsch, Spektrum Akademischer Verlag, 1995, ISBN3-86025-710-2
- Stephen Slade: Objektorientiertes gemeinsames Lisp, Prentice Hall, 1997, ISBN0-13-605940-6
- Richard P. Gabriel: Softwaremuster: Geschichten aus der Software -Community, Oxford University Press, 1998, ISBN0-19-512123-6,, PDF
- Taiichi Yuasa, Hiroshi G. Okuno: Advanced Lisp -Technologie, CRC, 2002, ISBN0-415-29819-9
- David B. Lamkins: Erfolgreiches Lisp: Wie man gemeinsames Lisps versteht und verwendet, BookFix.com, 2004. ISBN3-937526-00-5, Netz
- Peter Seibel: Praktisches gemeinsames Lisp, Apress, 2005. ISBN1-59059-239-5, Netz
- Doug Hoyte: Lambda überlassen, Lulu.com, 2008, ISBN1-4357-1275-7,, Netz
- George F. Luger, William A. Stubblefield: AI -Algorithmen, Datenstrukturen und Redewendungen in Prolog, Lisp und Java, Addison Wesley, 2008, ISBN0-13-607047-7,, PDF
- Conrad Barski: Land of Lisp: Lernen Sie, in Lisp zu programmieren, ein Spiel nach dem anderen!, Keine Stärkepresse, 2010, ISBN1-59327-200-6, Netz
- Pavel Penev: Lisp Web Tales, Leanpub, 2013, Netz
- Edmund Weitz: Gemeinsame Lisp -Rezepte, Apress, 2015, ISBN978-1-484211-77-9,, Netz
- Patrick M. Krusenotto: Funktionale programmierung und metaprogrammierung, interaktiv in Common Lisp, Springer Fachmedien Wiesbaden 2016, ISBN978-3-658-13743-4, Netz
Externe Links
- QuickLisp - Ein sehr beliebter und hochwertiger Bibliotheksmanager für Common Lisp
- Das Super CL Liste, eine kuratierte Liste gemeinsamer Lisp -Frameworks und Bibliotheken.
- Das Gemeinsames Lisp -Kochbuch, ein kollaboratives Projekt.
- Das Cliki, ein Wiki für frei und offen Gemeinsame Lisp-Systeme, die auf Unix-ähnlichen Systemen laufen.
- Eine der Hauptrepositorys für kostenlose gemeinsame LISP für Software ist Common-lisp.net.
- Lisp-Lang.org hat Dokumentation und eine Präsentation von Erfolgsgeschichten.
- Ein Überblick über die Geschichte des gemeinsamen LISP: "Geschichte". Common Lisp hyperspec.
- Gemeinsame LISP -schnelle Referenz - Ein kompakter Überblick über die gemeinsame LISP -Standardsprache.
- Planet Lisp Artikel über gemeinsames Lisp.
- Quickdocs Fasst Dokumentations- und Abhängigkeitsinformationen für viele QuickLisp -Projekte zusammen.