Common Lisp (oft abgekürzt mit CL) ist eine Multiparadigmen-Programmiersprache innerhalb der Sprachfamilie Lisp. Sie entstand aus einer 1981 gestarteten Bemühung unter Leitung von Scott Fahlman,Richard P. Gabriel erwähnt Scott Fahlman als Leiter des Common Lisp Projekts einen standardisierten Dialekt als Nachfolger von Maclisp (und dessen Varianten)Guy L. Steele Jr.: Common Lisp: The Language. Prentice Hall, ISBN 0-13-152414-3. zu finden und wurde 1994 als ANSI Common Lisp standardisiert.History im Common Lisp HyperSpec, abgerufen am 6. November 2016

Geschichte 1984 erschien die erste Ausgabe des Buches Common Lisp: The Language (kurz CLTL1), welches die erste Spezifikation der Sprache enthielt. Kurz darauf wurde das ANSI-Subkomitee X3J13 gegründet, um auf Basis der Spezifikation einen Standard zu erstellen. Die zweite Ausgabe des Buches (CLTL2) von 1990 enthielt Änderungen des Subkomitees und beschreibt einen Zwischenstand. 1994 erschien die endgültige Version des Standards (ANSI/X3.226-1994).Paul Graham: On Lisp. Prentice Hall, 1993, ISBN 0-13-030552-9

Syntax Common Lisp benutzt S-Expressions, um sowohl Source-Code als auch Daten darzustellen. Funktions- und Makroaufrufe werden als Listen geschrieben, die als erstes Element den Namen der Funktion bzw. des Makros enthalten. Kommentare werden mit ; eingeleitet oder mit #| |# umschlossen.

;; Addiere 2 und 2 (+ 2 2)

;; Definiere die Variable *p* als 3,1415 (defparameter *p* 3.1415)

;; Setze die vorher definierte Variable *p* auf 42 (setq *p* 42)

;; Eine Funktion, die ihr Argument quadriert (defun square (x) (* x x))

;; Quadriere 3 (square 3)

Datentypen Common Lisp unterstützt eine Vielzahl von Datentypen, mehr als viele andere Sprachen. Diese Typen sind hierarchisch angeordnet.

Skalare Typen Zahlen in Common Lisp sind vom Typ number. Untertypen von number sind unter anderem integer (Ganzzahlen), ratio (rationale Zahlen bzw. Brüche), real (Gleitkommazahlen) und complex (komplexe Zahlen). Arithmetik mit Ganzzahlen und Brüchen ist beliebig genau. Eine Klasse von Programmfehlern in Sprachen wie C, die durch überlaufende Ganzzahlen verursacht werden, ist in Common Lisp somit praktisch ausgeschlossen.

Der Common-Lisp-character-Typ ist nicht auf ASCII beschränkt, was nicht überrascht, da Lisp älter als ASCII ist. Viele Implementierungen unterstützen Unicode.siehe cliki.net/Unicode Support (englisch)

Der Typ symbol ist ein besonderes Merkmal fast aller Lispdialekte, in anderen Sprachfamilien hingegen größtenteils unbekannt. Ein Symbol in Common Lisp ist ähnlich einem Bezeichner in anderen Sprachen, da es als Variable benutzt wird und Werte zugewiesen bekommen kann. Da sie aber Objekte erster Klasse sind, können sie auch zu anderen Zwecken benutzt werden.

Datenstrukturen Common Lisp kennt eine Reihe vordefinierter Datenstrukturen. Dazu zählen unter anderem Hashtables, Datenverbünde (sogenannte structures), Klassen, Streams, Pfadnamen, mehrdimensionale Arrays und Folgen. Letztere umfassen klassische Lisp-Listen, aber auch Bitvektoren, allgemeine Vektoren und Zeichenketten.

Hashtables speichern Zuordnungen von Objekten. So kann zum Beispiel einer Zeichenkette eine Zahl zugewiesen werden oder einem Symbol eine Funktion. Bei Datenverbünden handelt es sich um beliebig verschachtelte Strukturen, die Daten jedes beliebigen Typs vorhalten können. Ein einzelner Verbund speichert in einer jeweils festen Menge von sogenannten slots Werte, die später nach Belieben verändert und extrahiert werden können. Strukturen bilden eine einfache Vererbungshierarchie. Arrays sind n-dimensionale Listen von Werten, die entweder alle denselben Typ haben müssen (in sogenannten homogenen Arrays), oder – im Falle von heterogenen Arrays – beliebig zusammengestellt sein können. Sie unterstützen die üblichen Matrixrechenoperationen und können auch in dynamisch veränderbaren Größen auftreten. Berechnungen mit homogenen, in ihrer Größe festgelegten Arrays können von Compilern meist sehr effizient übersetzt werden. Vektoren sind der Spezialfall von Arrays mit nur einer Dimension. Es gibt vordefinierte Vektortypen wie die Zeichenkette, ein Vektor von Zeichen, oder den Bitvektor, eine komfortable und effiziente Möglichkeit, Bits zu speichern und mit ihnen zu rechnen.

Klassische Lisp-Listen bestehen aus sogenannten CONS-Zellen. Damit sind geordnete Paare gemeint, deren erstes Element, der sogenannte CAR, einen Wert enthält, während deren zweites Element, der sogenannte CDR, auf die jeweils nächste Zelle oder im Falle des Listenendes auf das Symbol NIL zeigt. Im Grunde handelt es sich bei Lisp-Listen also um einfach verkettete Listen. Sie werden heute hauptsächlich verwendet, um Code darzustellen und mithilfe von Makros beliebig zu manipulieren – ein Mechanismus, der Common-Lisp-Programmierern einen Grad an Freiheit bietet, der bei anderen Programmiersprachen dem Sprachdesigner vorbehalten bleibt. Komplexere Daten speichert man für gewöhnlich in Klassen oder Verbünden, und Daten, mit denen man effizient rechnen möchte, in Arrays bzw. Vektoren.

Paketsystem Common Lisp enthält ein Paketsystem, das es erlaubt, Namensräume für Symbole zu definieren und Letztere zu im- und exportieren. Außerdem können der Bequemlichkeit und Lesbarkeit halber Abkürzungen bzw. Spitznamen für Pakete vergeben werden.

Symbole, die sich in anderen Namensräumen als dem aktuellen befinden, können angesprochen werden, indem man vor ihre Namen mit einem Doppelpunkt getrennt den jeweiligen Paketnamen schreibt. Beispielsweise zeigt der Name cl:format stets auf das FORMAT-Symbol im Paket CL, unabhängig davon, ob im aktuellen Paket möglicherweise eine Funktion definiert ist, die ebenfalls FORMAT heißt.

Funktionen In Common Lisp sind Funktionen normale Objekte, die als Parameter übergeben oder von einer Funktion zurückgegeben werden können. Dadurch können sehr allgemeine Operationen ausgedrückt werden.

Das Auswertungsschema für Funktionen ist sehr einfach. Wenn ein Ausdruck der Form (F A1 A2 …) vorliegt, kann angenommen werden, dass das Symbol mit dem Namen F: ein spezieller Operator ist (special operator). ein schon definiertes Makro ist. der Name einer Funktion ist.

Wenn F der Name einer Funktion ist, dann werden die Argumente A1, A2, … von links nach rechts ausgewertet und der entsprechenden Funktion als Parameter übergeben.

Definieren neuer Funktionen Das Makro defun definiert Funktionen. Eine Funktionsdefinition beschreibt den Namen der Funktion, die Namen aller Argumente und den Funktionsrumpf:

(defun square (x) (* x x))

Funktionsdeklarationen können Deklarationen beinhalten, die dem Compiler Hinweise zur Optimierung u. a. bzgl. Typen geben. Zusätzlich können auch sogenannte documentation strings oder kurz docstrings angegeben werden, die das Laufzeitsystem benutzen kann, um dem Benutzer interaktive Hilfe zu bieten.

(defun square (x) "Berechne das Quadrat von X." (declare (fixnum x) ; Typangabe für ein Argument (optimize (speed 3) (debug 0) (safety 1))) (the fixnum (* x x))) ; Typangabe für den Rückgabewert

Anonyme Funktionen (Funktionen ohne expliziten Namen) werden mittels des lambda-Operators (nach dem Lambda-Kalkül) erzeugt. Viele Common-Lisp-Programme benutzen Funktionen höherer Ordnung, bei denen es nützlich ist, anonyme Funktionen als Argumente zu übergeben.

Lese-, Kompilier- und Laufzeit Als Besonderheit gegenüber anderen Sprachen erlaubt Common Lisp es dem Programmierer, eigenen Code nicht nur zur Laufzeit auszuführen, sondern auch in drei anderen Phasen, der Lese-, der Kompilier- und der Ladezeit.

Lesezeit und Lesemakros Code, der während der Lesezeit ausgeführt wird, kann den Parser steuern und so eigene Syntax definieren. Meist geschieht dies in Form von sogenannten Lesemakros (read macros oder auch reader macros), die einzelnen Sonderzeichen zugewiesen werden und beliebigen Text in Code umwandeln können. So gibt es beispielsweise Lesemakros, die für arithmetische Ausdrücke die gewohnte Infix-Syntax bereitstellen und Ausdrücke wie 3 * (4 + 3) in Common Lisp gültig machen.

Auch ad hoc kann ein Programmierer Code zur Lesezeit ausführen, indem er sich des Standardlesemakros #. bedient. Der Ausdruck (+ #.(print 10) 20) beispielsweise gibt nicht nur bei seiner Ausführung 30 zurück, sondern druckt auch während des Einlesens des Ausdrucks selbst die Zahl 10 auf dem Bildschirm aus. Da diese Funktionalität bereits das bloße Einlesen von Ausdrücken, die beispielsweise über ein Netzwerk empfangen wurden, zu einem Sicherheitsproblem macht, kann sie über die Variable *read-eval* an- und ausgeschaltet werden.

Kompilierzeit und Lispmakros Common Lisp bietet, wie fast alle Lisp-Dialekte und im Gegensatz zu den meisten anderen Sprachen, die Möglichkeit, Code zur Kompilierzeit auszuführen und damit die den Programmcode darstellenden S-Ausdrücke beliebig zu manipulieren, zu generieren und umzuformen. Die Sprache sieht dafür in erster Linie die sogenannten Makros vor. Da Lispmakros auf der Ebene der Programmstruktur arbeiten und sich dadurch in die Sprache selbst perfekt einfügen, sind sie mit Makrosystemen anderer Sprachen nicht vergleichbar und würden daher eigentlich einen eigenen Namen verdienen.

Makros können auf alle Common-Lisp-Funktionalitäten, auch selbstdefinierte, zugreifen, wodurch ihnen sehr viele Möglichkeiten offenstehen, Code umzuformen. Common-Lisp-Programmierer verwenden Makros oft, um anwendungsspezifische Sprachen in Common Lisp einzubauen, die sich nahtlos in die Sprache einpassen und ihre Ausdrucksstärke erhöhen. Auch ist es möglich, Makros zur Bereitstellung neuer Programmierparadigmen zu nutzen.

So ist zum Beispiel das im ANSI-Standard enthaltene klassenbasierte Objektsystem CLOS metazirkulär als ein Satz von generischen Funktionen und Klassen implementierbar, über die eine Schicht von Makros gelegt wird, um die bequeme Definition von Klassen, generischen Funktionen und anderen CLOS-Sprachelementen zu ermöglichen. Wie die Implementierung von CLOS tatsächlich aussieht, hängt jedoch vom verwendeten Lispsystem ab und wird vom Standard nicht vorgeschrieben.

Variablenbindung Wie die meisten anderen Sprachen kennt auch Common Lisp das Konzept des Bindens von Werten an Namen. Es erweitert dieses Konzept jedoch durch zwei Aspekte: Einerseits können Variablennamen selbst als normale Objekte verwendet und zum Beispiel weitergegeben oder gespeichert werden, und andererseits stehen zwei ganz unterschiedliche Formen der Variablenbindung zur Verfügung. Der erstgenannte Aspekt wurde bereits im Abschnitt über Datentypen erläutert.

Lexikalische Bindung und lexikalische Variablen Common Lisp verwendet standardmäßig lexikalische Bindung (lexical scoping), ein Konzept, das Scheme seinerzeit in die Lisp-Welt eingeführt hat. Dabei sind Namen immer in einem bestimmten, abgeschlossenen Teil des Quelltexts gültig, so dass es bei der Bindung nicht zu Überschneidungen mit zuvor oder künftig definierten Bindungen kommen kann.

Da Bindungen in Common Lisp jederzeit erzeugt werden können und Überschneidungen ausgeschlossen sind, ist es möglich, mit ihrer Hilfe allein durch Funktionsdeklarationen Datenstrukturen zu erzeugen. Dabei nutzt man einen Effekt aus, den man closure nennt: das automatische Einfangen von Bindungen. Closures sind Funktionen und ihre Bindungen.

Möchte man beispielsweise den my-cons-Operator definieren, der ein Paar aus zwei Werten erzeugt, so könnte man auf die Idee kommen, diesen eine anonyme Funktion (also einen lambda-Ausdruck) zurückliefern zu lassen, die die beiden Werte eingefangen hat, und auf Anfrage, d. h. wenn sie mit einem Argument num aufgerufen wird, einen der beiden zurückliefert (und zwar den ersten Wert für num = 0 und sonst den zweiten):

(defun my-cons (x y) (lambda (num) (if (zerop num) x y)))

Man kann die von diesem Operator erzeugten Werte zum Beispiel wie folgt verwenden (man beachte: funcall ist der Operator zum Aufrufen von Funktionen, die in Variablen gespeichert sind):