common-lisp Tutoriel
Commencer avec Common-Lisp
Recherche…
Remarques
Ceci est une fonction simple hello world dans Common Lisp. Des exemples vont imprimer le texte Hello, World!
(sans les guillemets, suivi d'une nouvelle ligne) à la sortie standard.
Common Lisp est un langage de programmation largement utilisé de manière interactive en utilisant une interface appelée REPL. Le REPL (Read Eval Print Loop) permet de taper du code, de l’évaluer (voir) et de voir les résultats immédiatement. L'invite pour la REPL (à laquelle on tape le code à exécuter) est indiquée par CL-USER>
. Parfois, quelque chose d'autre que CL-USER
apparaîtra avant le >
mais ceci est toujours une REPL.
Après l'invite, il y a un code, généralement un seul mot (un nom de variable) ou un formulaire (une liste de mots / formes entre (
et )
) (un appel de fonction ou une déclaration, etc.). Sur la ligne suivante, il y aura toute sortie que le programme imprime (ou rien si le programme n’imprime rien), puis les valeurs renvoyées en évaluant l’expression. Normalement, une expression renvoie une valeur mais si elle renvoie plusieurs valeurs, elles apparaissent une fois par ligne.
Versions
Version | Date de sortie |
---|---|
Lisp commun | 1984-01-01 |
ANSI Common Lisp | 1994-01-01 |
Bonjour le monde
Ce qui suit est un extrait d'une session REPL avec Common Lisp dans laquelle un "Hello, World!" la fonction est définie et exécutée. Voir les remarques au bas de cette page pour une description plus détaillée d'une REPL.
CL-USER> (defun hello ()
(format t "Hello, World!~%"))
HELLO
CL-USER> (hello)
Hello, World!
NIL
CL-USER>
Ceci définit la "fonction" de zéro argument nommé hello
, qui écrira la chaîne "Hello, World!"
suivi d'une nouvelle ligne à la sortie standard et retourne NIL
.
Pour définir une fonction on écrit
(defun name (parameters...)
code...)
Dans ce cas, la fonction est appelée hello
, ne prend aucun paramètre et le code qu’elle exécute fait un appel de fonction. La valeur renvoyée par une fonction lisp est le dernier bit de code de la fonction à exécuter, donc hello
renvoie le résultat (format t "Hello, World!~%")
.
Dans lisp pour appeler une fonction, on écrit (function-name arguments...)
où function-name
est le nom de la fonction et arguments...
est la liste d'arguments (séparés par des espaces) de l'appel. Il y a des cas particuliers qui ressemblent à des appels de fonction mais qui ne sont pas, par exemple, dans le code ci-dessus, il n'y a pas de fonction defun
appelée, elle est traitée spécialement et définit une fonction à la place.
À la deuxième invite de la REPL, après avoir défini la fonction hello
, nous l’appelons sans paramètres en écrivant (hello)
. Cela appellera à son tour la fonction de format
avec les paramètres t
et "Hello, World!~%"
. La fonction format
produit une sortie formatée en fonction des arguments qui lui sont donnés (un peu comme une version avancée de printf
en C). Le premier argument lui indique où sortir, avec t
signifiant sortie standard. Le second argument lui indique quoi imprimer (et comment interpréter les paramètres supplémentaires). La directive (code spécial dans le deuxième argument) ~%
indique au format d’imprimer une nouvelle ligne (c’est-à-dire que sous UNIX, elle peut écrire \n
et sur Windows \r\n
). Le format retourne généralement NIL
(un peu comme NULL
dans les autres langues).
Après la deuxième invite, nous voyons que Hello, World
a été imprimé et à la ligne suivante que la valeur renvoyée était NIL
.
Bonjour, Nom
Ceci est un exemple légèrement plus avancé qui montre quelques fonctionnalités supplémentaires du lisp commun. Nous commençons par un simple Hello, World!
fonction et démontrer un développement interactif au REPL. Notez que tout texte à partir d' un point - virgule ;
, au reste de la ligne est un commentaire.
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>
Cela met en évidence certaines des fonctionnalités avancées de la fonction de format
de Common Lisp, ainsi que certaines fonctionnalités telles que les paramètres facultatifs et les arguments de mot-clé (par exemple :number
). Cela donne également un exemple de développement interactif à une REPL en langage courant.
Le programme simple Hello World dans REPL
Common Lisp REPL est un environnement interactif. Chaque formulaire écrit après l'invite est évalué et sa valeur est ensuite imprimée à la suite de l'évaluation. Ainsi, le programme le plus simple possible «Bonjour, Monde!» Dans Common Lisp est:
CL-USER> "Hello, World!"
"Hello, World!"
CL-USER>
Ce qui se passe ici est qu'un costant de chaîne est donné en entrée à la REPL, il est évalué et le résultat est imprimé. Ce que l'on peut voir dans cet exemple est que les chaînes, comme les nombres, les symboles spéciaux comme NIL
et T
et quelques autres littéraux, sont des formulaires auto- évaluables: c'est-à-dire qu'ils se évaluent eux-mêmes.
Expressions de base
Essayons une expression de base dans le 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>
Le bloc de construction de base d'un programme Common Lisp est le formulaire . Dans ces exemples, nous avons des formes de fonctions , c’est-à-dire des expressions, écrites sous forme de liste, dans lesquelles le premier élément est un opérateur (ou une fonction) et le reste des éléments les opérandes ”). L'écriture de formulaires dans le REPL entraîne leur évaluation. Dans les exemples, vous pouvez voir des expressions simples dont les arguments sont des nombres constants, des chaînes et des symboles (dans le cas de 'string
, qui est le nom d'un type). Vous pouvez également voir que les opérateurs arithmétiques peuvent prendre n'importe quel nombre d'arguments.
Il est important de noter que les parenthèses font partie intégrante de la syntaxe et ne peuvent pas être utilisées librement comme dans d'autres langages de programmation. Par exemple, ce qui suit est une erreur:
(+ 5 ((+ 2 4)))
> Error: Car of ((+ 2 4)) is not a function name or lambda-expression. ...
Dans Common Lisp, les formulaires peuvent également être des données, des symboles, des formes de macros, des formulaires spéciaux et des formes lambda. Ils peuvent être écrits pour être évalués, retourner zéro, une ou plusieurs valeurs, ou peuvent être donnés en entrée à une macro, qui les transforment sous d'autres formes.
Somme de la liste d'entiers
(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))
Expressions lambda et fonctions anonymes
Une fonction anonyme peut être définie sans nom via une expression Lambda . Pour définir ce type de fonctions, le mot-clé lambda
est utilisé à la place du mot-clé defun
. Les lignes suivantes sont toutes équivalentes et définissent des fonctions anonymes qui génèrent la somme de deux nombres:
(lambda (x y) (+ x y))
(function (lambda (x y) (+ x y)))
#'(lambda (x y) (+ x y))
Leur utilité est notable lors de la création de formulaires Lambda , c.-à-d. Un formulaire qui est une liste où le premier élément est l'expression lambda et les éléments restants sont les arguments de la fonction anonyme. Exemples ( exécution en ligne ):
(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)
Ressources d'apprentissage Common Lisp
Livres en ligne
Ce sont des livres librement accessibles en ligne.
- Practical Common Lisp de Peter Seibel est une bonne introduction à la technologie CL pour les programmeurs expérimentés, qui essaie depuis le début de mettre en évidence ce qui rend CL différent des autres langages.
- Common Lisp: Une introduction douce au calcul symbolique par David S. Touretzky est une bonne introduction pour les nouveaux venus en programmation.
- Common Lisp: Une approche interactive de Stuart C. Shapiro a été utilisée comme manuel de cours et des notes de cours accompagnent le livre sur le site Web.
- Common Lisp, le langage de Guy L. Steele est une description du langage Common Lisp. Selon le CLiki, il est obsolète, mais il contient de meilleures descriptions de la macro en boucle et du format que le Common Lisp Hyperspec.
- On Lisp de Paul Graham est un excellent livre pour les Lispers expérimentés.
- Let Over Lambda de Doug Hoyte est un livre avancé sur les macros Lisp. Plusieurs personnes ont recommandé que vous soyez à l'aise avec On Lisp avant de lire ce livre et que le démarrage soit lent.
Références en ligne
- Le Common Lisp Hyperspec est le document de référence de langage pour Common Lisp.
- Le Common Lisp Cookbook est une liste de recettes Lisp utiles. Contient également une liste d'autres sources en ligne d'informations sur la CL.
- Common Lisp Quick Reference a des feuilles de référence imprimables Lisp.
- Lispdoc.com recherche plusieurs sources d'informations Lisp (Common Lisp pratique, Lisp réussi, On Lisp, HyperSpec) pour la documentation.
- L1sp.org est un service de redirection pour la documentation.
Livres hors ligne
Ce sont des livres que vous devrez probablement acheter ou prêter dans une bibliothèque.
- ANSI Common Lisp de Paul Graham .
- Recettes Lisp communes par Edmund Weitz .
- Paradigmes de la programmation de l'intelligence artificielle a de nombreuses applications intéressantes de Lisp, mais n'est pas une bonne référence pour l'IA.
Communautés en ligne
- Le CLiki a une excellente page de démarrage . Une excellente ressource pour tout ce qui concerne CL. Possède une longue liste de livres Lisp .
- Common Lisp subreddit a beaucoup de liens utiles et de documents de référence dans la barre latérale.
- IRC: #lisp, #ccl, #sbcl et autres sur Freenode .
- Common-Lisp.net fournit l'hébergement pour de nombreux projets communs et groupes d'utilisateurs.
Bibliothèques
- Quicklisp est un gestionnaire de bibliothèque pour Common Lisp et possède une longue liste de bibliothèques prises en charge .
- Quickdocs héberge la documentation de la bibliothèque pour de nombreuses bibliothèques CL.
- Awesome CL est une liste organisée par les communautés de bibliothèques, de frameworks et d’autres éléments brillants, classés par catégorie.
Environnements Lisp préemballés
Ce sont des environnements d'édition Lisp faciles à installer et à utiliser car tout ce dont vous avez besoin est pré-packagé et pré-configuré.
- Portacle est un environnement Common Lisp portable et multiplateforme. Il embarque un Emacs légèrement personnalisé avec Slime, SBCL (une implémentation Common Lisp populaire), Quicklisp et Git. Aucune installation nécessaire, c'est donc un moyen très rapide et facile de démarrer.
- Lispbox est un IDE (Emacs + SLIME), un environnement Common Lisp (Clozure Common Lisp) et un gestionnaire de bibliothèque (Quicklisp), pré-emballés en tant qu'archives pour Windows, Mac OSX et Linux. Descendant de "Lisp in a Box" Recommandé dans le livre Practical Common Lisp.
- Non préemballé, mais SLIME transforme Emacs en IDE Common Lisp et dispose d'un manuel d'utilisation pour vous aider à démarrer. Nécessite une implémentation Common Lisp distincte.
Implémentations Lisp communes
Cette section répertorie certaines implémentations CL et leurs manuels. Sauf indication contraire, il s'agit d'implémentations de logiciels libres. Voir aussi la liste des implémentations Common Lisp du logiciel libre , et la liste des implémentations Common Lisp commerciales de Wikipedia .
- Allegro Common Lisp (ACL) et manuel . Commercial, mais a une édition Express gratuite et des vidéos de formation sur Youtube .
- CLISP et manuel .
- Clozure Common Lisp (CCL) et manuel .
- L'université Common Lisp de l'Université Carnegie Mellon (CMUCL) dispose d'un manuel et d'une autre page d' informations utiles .
- Embout Common Lisp (ECL) et manuel .
- LispWorks et manuel . Commercial, mais a une édition personnelle avec quelques limitations .
- Steel Bank Common Lisp (SBCL) et manuel .
- Scieneer Common Lisp (SCL) et manual sont des implémentations commerciales Linux et Unix, mais ont une version d'évaluation gratuite et une utilisation non commerciale sans restriction .