common-lisp Tutorial
Erste Schritte mit common-lisp
Suche…
Bemerkungen
Dies ist eine einfache Hallo Weltfunktion in Common Lisp. Beispiele drucken den Text Hello, World!
(ohne Anführungszeichen; gefolgt von einem Zeilenumbruch) zur Standardausgabe.
Common Lisp ist eine Programmiersprache, die weitgehend interaktiv mit einer als REPL bezeichneten Schnittstelle verwendet wird. Die REPL (Read Eval Print Loop) ermöglicht das Eingeben von Code, das Auswerten (Ausführen) und das sofortige Anzeigen der Ergebnisse. Die Eingabeaufforderung für die REPL (an welcher Stelle der einzugebende Code CL-USER>
wird) wird durch CL-USER>
angezeigt. Manchmal erscheint vor dem >
etwas anderes als CL-USER
, aber dies ist immer noch eine REPL.
Nach der Aufforderung folgt Code, normalerweise entweder ein einzelnes Wort (dh ein Variablenname) oder ein Formular (eine Liste von Wörtern / Formularen, die zwischen (
und )
) (dh ein Funktionsaufruf oder eine Deklaration usw.) In der nächsten Zeile wird jede Ausgabe angezeigt, die das Programm druckt (oder nichts, wenn das Programm nichts druckt) und dann die durch Auswertung des Ausdrucks zurückgegebenen Werte. Normalerweise gibt ein Ausdruck einen Wert zurück, aber wenn er mehrere Werte zurückgibt, werden sie einmal pro Zeile angezeigt.
Versionen
Ausführung | Veröffentlichungsdatum |
---|---|
Common Lisp | 1984-01-01 |
ANSI Common Lisp | 1994-01-01 |
Hallo Welt
Was folgt, ist ein Auszug aus einer REPL-Sitzung mit Common Lisp, in der ein "Hallo, Welt!" Funktion ist definiert und ausgeführt. Eine ausführlichere Beschreibung einer REPL finden Sie in den Anmerkungen unten auf dieser Seite.
CL-USER> (defun hello ()
(format t "Hello, World!~%"))
HELLO
CL-USER> (hello)
Hello, World!
NIL
CL-USER>
Dies definiert die "Funktion" der Nullargumente namens " hello
, die die Zeichenfolge "Hello, World!"
gefolgt von einem Zeilenumbruch zur Standardausgabe und NIL
.
Um eine Funktion zu definieren, schreiben wir
(defun name (parameters...)
code...)
In diesem Fall heißt die Funktion hello
, nimmt keine Parameter auf und führt einen Funktionsaufruf aus. Der von einer Lisp-Funktion zurückgegebene Wert ist das letzte auszuführende Code-Bit in der Funktion. hello
gibt also zurück, was (format t "Hello, World!~%")
Zurückgegeben wird.
Um eine Funktion aufzurufen, schreibt man (function-name arguments...)
wobei function-name
der Name der Funktion ist und arguments...
die (durch Leerzeichen getrennte) Liste von Argumenten für den Aufruf. Es gibt einige Sonderfälle, die wie Funktionsaufrufe aussehen, aber im obigen Code nicht defun
Es gibt keine defun
Funktion, die aufgerufen wird. Sie wird speziell behandelt und definiert stattdessen eine Funktion.
An der zweiten Aufforderung der REPL, nachdem wir die hello
Funktion definiert haben, rufen wir sie ohne Parameter auf, indem wir schreiben (hello)
. Dies ruft die format
mit den Parametern t
und "Hello, World!~%"
. Die format
erzeugt eine formatierte Ausgabe basierend auf den angegebenen Argumenten (ein bisschen wie eine erweiterte Version von printf
in C). Das erste Argument gibt an, wohin die Ausgabe erfolgen soll, wobei t
Standardausgabe bedeutet. Das zweite Argument gibt an, was gedruckt werden soll (und wie zusätzliche Parameter zu interpretieren sind). Die Direktive (spezieller Code im zweiten Argument) ~%
weist format an, einen Zeilenumbruch zu drucken (dh unter UNIX könnte es \n
und unter Windows \r\n
schreiben). Format gibt normalerweise NIL
(ein bisschen wie NULL
in anderen Sprachen).
Nach der zweiten Aufforderung sehen wir, dass Hello, World
gedruckt wurde und in der nächsten Zeile war der zurückgegebene Wert NIL
.
Hallo, Name
Dies ist ein etwas fortgeschritteneres Beispiel, das einige weitere Funktionen von allgemeinem Lisp zeigt. Wir beginnen mit einem einfachen Hello, World!
Funktion und Demonstration der interaktiven Entwicklung an der REPL. Beachten Sie, dass jeder Text aus einem Semikolon ;
an den Rest der Zeile ist ein Kommentar.
CL-USER> (defun hello ()
(format t "Hello, World!~%")) ;We start as before
HELLO
CL-USER> (hello)
Hello, World!
NIL
CL-USER> (defun hello-name (name) ;A function to say hello to anyone
(format t "Hello, ~a~%" name)) ;~a prints the next argument to format
HELLO-NAME
CL-USER> (hello-name "Jack")
Hello, Jack
NIL
CL-USER> (hello-name "jack") ;doesn't capitalise names
Hello, jack
NIL
CL-USER> (defun hello-name (name) ;format has a feature to convert to title case
(format t "Hello, ~:(~a~)~%" name)) ;anything between ~:( and ~) gets it
WARNING: redefining COMMON-LISP-USER::HELLO-NAME in DEFUN
HELLO-NAME
CL-USER> (hello-name "jack")
Hello, Jack
NIL
CL-USER> (defun hello-name (name)
(format t "Hello, ~:(~a~)!~%" name))
WARNING: redefining COMMON-LISP-USER::HELLO-NAME in DEFUN
HELLO-NAME
CL-USER> (hello-name "jack") ;now this works
Hello, Jack!
NIL
CL-USER> (defun hello (&optional (name "world")) ;we can take an optional argument
(hello-name name)) ;name defaults to "world"
WARNING: redefining COMMON-LISP-USER::HELLO in DEFUN
HELLO
CL-USER> (hello)
Hello, World!
NIL
CL-USER> (hello "jack")
Hello, Jack!
NIL
CL-USER> (hello "john doe") ;note that this capitalises both names
Hello, John Doe!
NIL
CL-USER> (defun hello-person (name &key (number))
(format t "Hello, ~a ~r" name number)) ;~r prints a number in English
HELLO-PERSON
CL-USER> (hello-person "Louis" :number 16) ;this doesn't quite work
Hello, Louis sixteen
NIL
CL-USER> (defun hello-person (name &key (number))
(format t "Hello, ~:(~a ~:r~)!" name number)) ;~:r prints an ordinal
WARNING: redefining COMMON-LISP-USER::HELLO-PERSON in DEFUN
HELLO-PERSON
CL-USER> (hello-person "Louis" :number 16)
Hello, Louis Sixteenth!
NIL
CL-USER> (defun hello-person (name &key (number))
(format t "Hello, ~:(~a ~@r~)!" name number)) ;~@r prints Roman numerals
WARNING: redefining COMMON-LISP-USER::HELLO-PERSON in DEFUN
HELLO-PERSON
CL-USER> (hello-person "Louis" :number 16)
Hello, Louis Xvi!
NIL
CL-USER> (defun hello-person (name &key (number)) ;capitalisation was wrong
(format t "Hello, ~:(~a~) ~:@r!" name number))
WARNING: redefining COMMON-LISP-USER::HELLO-PERSON in DEFUN
HELLO-PERSON
CL-USER> (hello-person "Louis" :number 16) ;thats better
Hello, Louis XVI!
NIL
CL-USER> (hello-person "Louis") ;we get an error because NIL is not a number
Hello, Louis ; Evaluation aborted on #<SB-FORMAT:FORMAT-ERROR {1006641AB3}>.
CL-USER> (defun say-person (name &key (number 1 number-p)
(title nil) (roman-number t))
(let ((number (if number-p
(typecase number
(integer
(format nil (if roman-number " ~:@r" " ~:(~:r~)") number))
(otherwise
(format nil " ~:(~a~)" number)))
"")) ; here we define a variable called number
(title (if title
(format nil "~:(~a~) " title)
""))) ; and here one called title
(format nil "~a~:(~a~)~a" title name number))) ;we use them here
SAY-PERSON
CL-USER> (say-person "John") ;some examples
"John"
CL-USER> (say-person "john doe")
"John Doe"
CL-USER> (say-person "john doe" :number "JR")
"John Doe Jr"
CL-USER> (say-person "john doe" :number "Junior")
"John Doe Junior"
CL-USER> (say-person "john doe" :number 1)
"John Doe I"
CL-USER> (say-person "john doe" :number 1 :roman-number nil) ;this is wrong
"John Doe First"
CL-USER> (defun say-person (name &key (number 1 number-p)
(title nil) (roman-number t))
(let ((number (if number-p
(typecase number
(integer
(format nil (if roman-number " ~:@r" " the ~:(~:r~)") number))
(otherwise
(format nil " ~:(~a~)" number)))
""))
(title (if title
(format nil "~:(~a~) " title)
"")))
(format nil "~a~:(~a~)~a" title name number)))
WARNING: redefining COMMON-LISP-USER::SAY-PERSON in DEFUN
SAY-PERSON
CL-USER> (say-person "john doe" :number 1 :roman-number nil) ;thats better
"John Doe the First"
CL-USER> (say-person "louis" :title "king" :number 16 :roman-number nil)
"King Louis the Sixteenth"
CL-USER> (say-person "louis" :title "king" :number 16 :roman-number t)
"King Louis XVI"
CL-USER> (defun hello (&optional (name "World") &rest arguments) ;now we will just
(apply #'hello-name name arguments)) ;pass all arguments to hello-name
WARNING: redefining COMMON-LISP-USER::HELLO in DEFUN
HELLO
CL-USER> (defun hello-name (name &rest arguments) ;which will now just use
(format t "Hello, ~a!" (apply #'say-person name arguments))) ;say-person
WARNING: redefining COMMON-LISP-USER::HELLO-NAME in DEFUN
HELLO-NAME
CL-USER> (hello "louis" :title "king" :number 16) ;this works now
Hello, King Louis XVI!
NIL
CL-USER>
Hier werden einige der erweiterten Funktionen der format
von Common Lisp sowie einige optionale Parameter und Schlüsselwortargumente (z. B. :number
) hervorgehoben. Dies ist auch ein Beispiel für die interaktive Entwicklung einer REPL in Common Lisp.
Das einfache Hello World-Programm in REPL
Common Lisp REPL ist eine interaktive Umgebung. Jedes nach der Eingabeaufforderung geschriebene Formular wird ausgewertet und anschließend als Ergebnis der Auswertung gedruckt. Das einfachste mögliche "Hallo, Welt!" - Programm in Common Lisp ist:
CL-USER> "Hello, World!"
"Hello, World!"
CL-USER>
Was hier passiert, ist, dass ein String-Costant in die REPL eingegeben wird, ausgewertet wird und das Ergebnis gedruckt wird. Aus diesem Beispiel ist ersichtlich, dass Zeichenfolgen wie Zahlen, Sonderzeichen wie NIL
und T
und einige andere Literale sich selbst auswertende Formen darstellen.
Grundausdrücke
Versuchen wir einen grundlegenden Ausdruck in der REPL:
CL-USER> (+ 1 2 3)
6
CL-USER> (- 3 1 1)
1
CL-USER> (- 3)
-3
CL-USER> (+ 5.3 (- 3 2) (* 2 2))
10.3
CL-USER> (concatenate 'string "Hello, " "World!")
"Hello, World!"
CL-USER>
Der Grundbaustein eines Common Lisp-Programms ist das Formular . In diesen Beispielen haben wir Funktionsformen , d. H. Als Liste geschriebene Ausdrücke, in denen das erste Element ein Operator (oder eine Funktion) und die übrigen Elemente die Operanden sind (dies wird als "Präfixnotation" oder "Polnische Notation" bezeichnet) ”). Das Schreiben von Formularen in der REPL bewirkt deren Auswertung. In den Beispielen können Sie einfache Ausdrücke sehen, deren Argumente konstante Zahlen, Strings und Symbole sind (im Fall von 'string
, der Name eines Typs). Sie können auch sehen, dass arithmetische Operatoren eine beliebige Anzahl von Argumenten annehmen können.
Es ist wichtig zu beachten, dass Klammern ein wesentlicher Bestandteil der Syntax sind und nicht wie in anderen Programmiersprachen frei verwendet werden können. Zum Beispiel ist das Folgende ein Fehler:
(+ 5 ((+ 2 4)))
> Error: Car of ((+ 2 4)) is not a function name or lambda-expression. ...
In Common Lisp-Formularen können auch Daten, Symbole, Makroformulare, Sonderformen und Lambda-Formulare verwendet werden. Sie können geschrieben werden, um ausgewertet zu werden, null, einen oder mehrere Werte zurückzugeben, oder sie können als Eingabe in ein Makro eingegeben werden, das sie in andere Formen transformiert.
Summe der Liste der ganzen Zahlen
(defun sum-list-integers (list)
(reduce '+ list))
; 10
(sum-list-integers '(1 2 3 4))
; 55
(sum-list-integers '(1 2 3 4 5 6 7 8 9 10))
Lambda-Ausdrücke und anonyme Funktionen
Eine anonyme Funktion kann ohne Namen über einen Lambda-Ausdruck definiert werden . Für die Definition dieser Funktionstypen wird anstelle des Schlüsselworts defun
das Schlüsselwort lambda
verwendet. Die folgenden Zeilen sind alle äquivalent und definieren anonyme Funktionen, die die Summe zweier Zahlen ausgeben:
(lambda (x y) (+ x y))
(function (lambda (x y) (+ x y)))
#'(lambda (x y) (+ x y))
Ihre Nützlichkeit macht sich beim Erstellen von Lambda-Formularen bemerkbar, z. B. bei einem Formular, bei dem das erste Element der Lambda-Ausdruck ist und die übrigen Elemente die Argumente der anonymen Funktion sind. Beispiele ( Online-Ausführung ):
(print ((lambda (x y) (+ x y)) 1 2)) ; >> 3
(print (mapcar (lambda (x y) (+ x y)) '(1 2 3) '(2 -5 0))) ; >> (3 -3 3)
Allgemeine Lisp-Lernressourcen
Online-Bücher
Dies sind Bücher, die online frei zugänglich sind.
- Practical Common Lisp von Peter Seibel ist eine gute Einführung in CL für erfahrene Programmierer, die von Anfang an hervorheben möchte, was CL von anderen Sprachen unterscheidet.
- Common Lisp: Eine sanfte Einführung in die symbolische Berechnung von David S. Touretzky ist eine gute Einführung für Programmier- Neulinge .
- Common Lisp: Ein interaktiver Ansatz von Stuart C. Shapiro wurde als Lehrbuch verwendet, und Kursnotizen begleiten das Buch auf der Website.
- Common Lisp, die Sprache von Guy L. Steele ist eine Beschreibung der Common Lisp-Sprache. Laut CLiki ist es veraltet, enthält jedoch bessere Beschreibungen des Schleifenmakros und des Formats als das Common Lisp Hyperspec.
- On Lisp von Paul Graham ist ein großartiges Buch für erfahrene Lispers.
- Let Over Lambda von Doug Hoyte ist ein fortgeschrittenes Buch über Lisp Macros. Mehrere Personen haben empfohlen , sich mit On Lisp vertraut zu machen, bevor Sie dieses Buch lesen, und der Start ist langsam.
Online-Referenzen
- Die Common Lisp Hyperspec ist das Referenzdokument für Common Lisp.
- Das Common Lisp Cookbook enthält eine Liste nützlicher Lisp-Rezepte. Enthält auch eine Liste anderer Online-Quellen für CL-Informationen.
- Die allgemeine Lisp-Kurzanleitung enthält druckbare Lisp-Referenzblätter.
- Lispdoc.com durchsucht mehrere Lisp-Informationsquellen (Practical Common Lisp, Successful Lisp, On Lisp, die HyperSpec) nach Dokumentation.
- L1sp.org ist ein Weiterleitungsdienst für Dokumentation.
Offline-Bücher
Dies sind Bücher, die Sie wahrscheinlich kaufen oder aus einer Bibliothek ausleihen müssen.
- ANSI Common Lisp von Paul Graham .
- Gemeinsame Lisp Rezepte von Edmund Weitz .
- Paradigmen der künstlichen Intelligenz Programmierung hat viele interessante Anwendungen von Lisp, ist aber keine gute Referenz für die KI mehr.
Online-Communities
- Das CLiki hat eine großartige Erste Schritte-Seite . Eine großartige Ressource für alle Dinge CL. Verfügt über eine umfangreiche Liste von Lisp-Büchern .
- Common Lisp subreddit enthält zahlreiche nützliche Links und Referenzdokumente in der Seitenleiste.
- IRC: #lisp, #ccl, #sbcl und andere auf Freenode .
- Common-Lisp.net bietet Hosting für viele gängige Lisp-Projekte und Benutzergruppen.
Bibliotheken
- Quicklisp ist Bibliotheksmanager für Common Lisp und hat eine lange Liste unterstützter Bibliotheken .
- In Quickdocs befindet sich die Bibliotheksdokumentation für viele CL-Bibliotheken.
- Awesome CL ist eine kuratierte Liste von Bibliotheken, Frameworks und anderen glänzenden Dateien, die nach Kategorien sortiert sind.
Vorgefertigte Lisp-Umgebungen
Dies sind Lisp-Bearbeitungsumgebungen, die einfach zu installieren sind und mit denen Sie beginnen können, da alles, was Sie benötigen, vorgepackt und vorkonfiguriert ist.
- Portacle ist eine tragbare und plattformübergreifende Common Lisp-Umgebung. Es enthält einen leicht angepassten Emacs mit Slime, SBCL (eine beliebte Common Lisp-Implementierung), Quicklisp und Git. Es ist keine Installation erforderlich, daher ist dies eine sehr schnelle und einfache Möglichkeit, um loszulegen.
- Lispbox ist eine IDE- (Emacs + SLIME), Common Lisp-Umgebung (Clozure Common Lisp) und Bibliotheksmanager (Quicklisp), die als Archive für Windows, Mac OSX und Linux vorinstalliert ist. Nachkomme von "Lisp in a Box", empfohlen im praktischen Buch "Lisp".
- Nicht vorverpackt, aber SLIME verwandelt Emacs in eine Common Lisp IDE und verfügt über ein Benutzerhandbuch , das Ihnen den Einstieg erleichtert. Erfordert eine separate Common Lisp-Implementierung.
Gemeinsame Lisp-Implementierungen
In diesem Abschnitt werden einige gängige CL-Implementierungen und deren Handbücher aufgeführt. Wenn nicht anders angegeben, handelt es sich hierbei um freie Software-Implementierungen. Siehe auch die Cliki-Liste der freien Software-Common-Lisp-Implementierungen und die Wikipedia-Liste der kommerziellen Common-Lisp-Implementierungen .
- Allegro Common Lisp (ACL) und Handbuch . Kommerziell, hat aber eine kostenlose Express Edition und Schulungsvideos auf Youtube .
- CLISP und Handbuch .
- Clozure Common Lisp (CCL) und Handbuch .
- Carnegie Mellon University Common Lisp (CMUCL) , hat ein Handbuch und andere nützliche Informationsseiten .
- Integrierbares Common Lisp (ECL) und Handbuch .
- LispWorks und Handbuch . Kommerziell, hat aber eine Personal Edition mit einigen Einschränkungen .
- Stahlbank Common Lisp (SBCL) und Handbuch .
- Scieneer Common Lisp (SCL) und Handbuch ist eine kommerzielle Linux- und Unix-Implementierung, hat jedoch eine uneingeschränkte kostenlose Evaluierungsversion und nicht-kommerzielle Nutzung .