************************************************************************#
* *
* Fichier: /u2/fturi/use-lisp.txt *
* *
* Contenu: fichier d'aide sur le Common Lisp (version AKCL) *
*_______________________________________________________________________*
* Date : 01/june/92 *
* *
* Auteur : Francois TURI (fturi) *
* *
*************************************************************************
1) interpreteur lisp
machine :
rlogin descartes
akcl
commande: akcl
quitter: (bye)
toplevel: :q
compilation: (compile 'fn_name) sous napier
2)
(load "nom-fichier") -> T
(describe 'objet)
(sys:doc 'objet 'comment)
(sys:lambda-list 'fonction)
UTILSATION DES PARAMETRES OPTIONELS
-----------------------------------
EX: declaration (defun a-star node goal-node &key (debug-node nil))
utilisation (a-star '(0 0) '(3 3) :debug-mode 't))
declaration (defun toto element &rest suite-de-la-liste)
(format t "2eme element ~a" (second suite-de-la-liste)) )
utilisation (toto regulier extra1 extra2)
REM: - &KEY et &REST ne peuvent etre utilise en meme temps
- On ne peut declarer qu'une variable &key, &optional
&aux
&aux: sert a faire un calcul prealable comme pour un let
&key: sert a reperer un parametre differencie
&optional: rajout d'un seul parametre
&rest: rajout sous forme de liste des parametres en trop
a) Utilisation de &optional &key et &aux
(defun toto (x &optional (a 6) &key(z -1) &aux (y
(+ x x)) )
(format t "~% x= ~a" x)
(format t "~% y= ~a" y)
(format t "~% z= ~a" z)
(format t "~% a= ~a" a)
)
>(toto 1)
x= 1
y= 2
z= -1
a= 6
NIL
>(toto 1 10)
>(toto 1 10)
x= 1
y= 2
z= -1
a= 10
>(toto 1 3 :z 4)
x= 1
y= 2
z= 4
a= 3
NIL
b) Utilisation de &optional &rest et &aux
(defun toto (x &optional (a 6) &rest corps
&aux (y (+ x a)) )
(format t "~% x= ~a" x)
(format t "~% y= ~a" y)
(format t "~% a= ~a" a)
(format t "~% corps= ~a" corps)
)
>(toto 1 2 'a 'b 'c)
x= 1
y= 3
a= 2
corps= (A B C)
Remarque: les valeurs par defauts peuvent etre omises -> nil
SYNTAXE DU IF
=============
(if condition
clause-alors
clause-else)
NULL: 'NIL
TRUE: 'T
Effet de bord
CAR -> (RPLCA objet-cible nvel-element)
---------------------------------------
>(setq abc '(1 . 2))
(1 . 2)
>(rplaca abc 'z)
(Z . 2)
>abc
(Z . 2)
!! (rplaca aba (cons 1 abc)) -> cerclist !!!
CDR -> (RPLACD objet-cible nvel-element)
-----------------------------------------
>(setq abc '(1 . 2))
(1 . 2)
>(rplacd abc '@)
(1 . @)
>abc
(1 . @)
APPEND -> NCONC ( <list1> <list2> ...)
--------------------------------------
MAKE-LIST <size> [:initial-element <initial element>)
SYNTAXE DU COND
===============
(cond
(test1 clause1)
(test2 clause2)
('T defaultclause)
)
(cond ('T 'A))
A
(cond ('NIL 'A)('T 'B))
B
(defun ex (elmt liste)
(format t "~% element: ~a liste: ~a" elmt liste)
(cond
(
(equal liste 'NIL)
'NIL
)
(
(equal elmt (car liste))
liste
)
(
'T
(ex elmt (cdr liste))
)
) )
(ex 'a '(a b c d))
element: A liste: (A B C D)
(A B C D)
(ex 'c '(a b c d))
element: C liste: (A B C D)
element: C liste: (B C D)
element: C liste: (C D)
(C D)
SYNTAXE DU MAPCAR -> Liste d'application de chaque CAR
(MAPC version effet de bord sur variable origine)
======================================================
(mapcar #'(definition-of-fonction one-argument)
list
)
>(mapcar #'numberp '(A B C 1 2 3 D E F))
(NIL NIL NIL T T T NIL NIL NIL)
>(mapcar #'(lambda (x) (+ x x)) '(1 2 3 4 5 6 7))
(2 4 6 8 10 12 14)
SYNTAXE DU MAPLIST -> Liste d'application de chaque CDR
(MAPCON version effet de bord sur variable origine)
======================================================
>(maplist #'list '(1 2 3 4 5 6 7))
((1 2 3 4 5 6 7) (2 3 4 5 6 7) (3 4 5 6 7) (4 5 6 7) (5 6 7) (6 7)
(7))
SYNTAXE DE MAPL version effet de bord
>(mapl #'print '(1 2 3 4 5 6 7))
(1 2 3 4 5 6 7)
(2 3 4 5 6 7)
(3 4 5 6 7)
(4 5 6 7)
(5 6 7)
(6 7)
(7)
(1 2 3 4 5 6 7)
SYNTAXE DU DOLIST (Dolist (indice list) <utilisation de list>)
=================
Effet de bord seulement, renvoit tjs nil
ex:
>(dolist (toto '(1 2 3 4 5 6 7)) (print toto))
1
2
3
4
5
6
7
NIL
ACCES A UN ELEMENT dans une ALIST
=================================
>(first '((1 a b c) (2 d e) (3 f g) (4 h i j) (5 k l m)))
(1 A B C)
>(last '((1 a b c) (2 d e) (3 f g) (4 h i j) (5 k l m)))
((5 K L M))
>(second '((1 a b c) (2 d e) (3 f g) (4 h i j) (5 k l m)))
(2 D E)
et puis: third. fourth, fifth, sixth ...
>(nth 4 '((1 a b c) (2 d e) (3 f g) (4 h i j) (5 k l m)))
(5 K L M)
TEST EXISTENCE ELEMENT: (SOME predicat element)
======================
(some predicat liste)
ex:
>(some 'evenp '(1 2 3 4 5 6 3 2 1))
T
>(some 'evenp '(1 3 5 7 9))
NIL
CONSTRUCTION DE LISTE
=====================
>(list 'a '(a c) '(e f))
(A (A C) (E F))
UTILISATION de ` de , et de ,@
==============================
, evalue l'argument en gardant sa structure ()
>(setf toto `(print ,letchi 213))
(PRINT (A B C 1 2 3 D E F) 213)
>toto
(PRINT (A B C 1 2 3 D E F) 213)
,@ evalue l'argument en retirant les ()
>(setf toto `(print ,@letchi 213))
(PRINT A B C 1 2 3 D E F 213)
>toto
(PRINT A B C 1 2 3 D E F 213)
Application: Ecriture de macro
==============================
Remarque: Il est particulierement decommande d'ecrire des macro
recursive => utiliser fonction auxiliare ou fonctions de mapage.
Regle: Une macro est une fonction de reecriture d'un element par
l'application d'une fonction au moment de sa definition.
Cette reecriture peut etre recusive eventuellement (tres
dangereux)
En consequence la macro n'a access qu'au nom des arguments
et non a leur valaur. Elle retourne une liste qui peut faire reference
a la valeur des arguments.
Remarque une macro par effet de bord n'a pas de sens puisque
cet effet de bord s'effectuera au moment de la definition de la macro.
Une macro est en fait deux fois evaluee. Le corps de la macro
est evaluee tout de suite pour generer une liste. Cette liste retournee
sera evaluee normalement ensuite comme tout argument LISP.
Il faut etre sur a ce moment la que tout l'environement existe.
En general un bon moyen d'ecrire une macro consiste a placer
un ` au debut et d'ajouter a toutes les occurences des variables un
,.
Cela marche a condition que la fonction puisse fonctionner, c'est a
dire
que la macro n'apporte qu'une facilite de plus mais si on veut utiliser
l'interet principal des macro c'est a dire avoir acces au nom des arguments
il est alors necessaire de reflechir en terme de macro et de construire
un programme traitant uniquement le nom des arguments et non leur valeur
et de renvoyer une liste pouvant faire reference au nom des variables
sous
la forme 'nom-arg et leurs valeurs sous la forme nom-arg. Ne pas oublier
que la liste retournee sera evaluee lors de l'utilisation de la macro.
Exemple de macro utilisant le nom et la valeur des arguments
(defun visuvar (var arg)
`(format t "~% Parametre: ~a = ~a" ',var ,arg)
)
(defmacro visu (fn variables)
(append
`(progn)
(list
`(format t "~%Function: ~a" ',fn)
(if (atom variables)
(visuvar variables variables)
(append `(progn)
(mapcar '(lambda (x) (visuvar
x x)) variables)
)
)
`(format t "~%-*-*-*-*-*-*-*~%")
) ) )
>(defun toto (x y) (visu toto (x y)))
TOTO
>(toto 'a 'b)
Function: TOTO
Parametre: X = A
Parametre: Y = B
-*-*-*-*-*-*-*
NIL
(defun voir-macro(x) (eval (print (macroexpand x))))
UTILISATION DU LET (evaluation en //)
=====================================
(let (
(Premiere-Var Valeur)
(Deuxieme-Var Valeur)
....
)
(Corps fonction)
)
UTILISATION DU MEMBER
=====================
>(member '3 '(1 2 3 4 5))
(3 4 5)
>(member '3 '((1 a)(2 b)(3 c)(4 d)))
NIL
UTILISATION DU APPEND
=====================
>(append '(a b c d) '(e f g h))
(A B C D E F G H)
UTILISATION DES LIST
====================
>(setf aliste '((1 a b c)(2 d e f)(3 g h i)))
((1 A B C) (2 D E F) (3 G H I))
>(symbolp 'aliste)
T
>(assoc 2 aliste)
(2 D E F)
>(setf pliste '(1 a b c 2 d e f 3 g h i))
(1 A B C 2 D E F 3 G H I)
>(member 2 aliste)
NIL
>(member 2 pliste)
(2 D E F 3 G H I)
>(substitute '(2 . b) '@ '((1 . A) (2 . B) (3 . C) (4 . D) (5
. E)))
((1 . A) (2 . B) (3 . C) (4 . D) (5 . E))
>(substitute '@ 'a '(A B C D E F B C A))
(@ B C D E F B C @)
UTILISATION DES PLISTES
=======================
Struture: ( CLE info CLE (info1 info2 ..) CLE (info4 info5))
Elles sont de natures differentes pour set et get
>(setf (get 'harry 'age) 30)
30
>(symbol-plist 'harry)
(AGE 30)
Acces a un element:
>(getf plist1 2)
(E F G)
Modification d'un element (effet de bord):
(SETF pointeur_ou_liste nouvelle_valeur)
>(setf (getf plist1 2) '(ee ff gg))
(EE FF GG)
>>plist1
(1 (A B C D) 2 (EE FF GG) 3 (H I J K))
Suppresion d'un element:
>(remf plist2 'a)
T
>plist2
(B (5 6 7) C (7 8 10 11))
FUNCALL et APPLY
================
funcall recupere le nom d'une fonction
--------------------------------------
>(defun lam (x) (+ x x))
LAM
>(setf vlam 'lam)
LAM
>(funcall 'lam 4)
8
>(funcall '(lambda (x) (+ x x)) 10)
20
apply a besoin d'une variable
-----------------------------
>(setf vlam 'lam)
LAM
>(apply vlam '(9))
18
>(funcall vlam 6)
12
mais:
>(apply lam '(9))
Error: The variable LAM is unbound.
PREDICATS
=========
Liste vide (valable seulement pour LISTE)
>(endp nil)
T
>(endp '(nil))
NIL
>(not t)
NIL
>(not nil)
T
>(numberp 4)
T
>(consp '(1 2 3))
T
>(consp '(1 2))
T
>(listp '(1 . 2))
T
mais
>(consp nil)
NIL
>(listp nil)
T
>(boundp 'iznogoud)
NIL
>(setq iznogoud 5)
5
>(boundp 'iznogoud)
T
QUELQUE LISTES UTILES et FONCTIONS LAMBDA
=========================================
(setf chiffre '(1 2 3 4 5 6 3 2 1))
(setf chiffrer (reverse chiffre))
(setf lettre '(a b c d e f b c a))
(setf lettrer (reverse lettre))
(setf letchi '(a b c 1 2 3 c b a))
(setf chilet '(1 2 3 a b c 3 2 1))
(setf list1 '( (1 a b c) (2 d e) (3 f g h) ))
(setf list2 '( (a 1 2 3) (b 4 5) (c 6 7 8) ))
(setf plist1 '( 1 (a b c d) 2 (e f g) 3 (h i j k) ))
(setf plist2 '( a (1 2 3 4) b (5 6 7) c (7 8 10 11) ))
(setf alist1 '( (1 . a) (2 . b) (3 . c) (2 . b) (1 . a) ))
(setf alist2 '( (a . 1) (b . 2) (c . 3) (b . 2) (a . 1) ))
(setf paire '(1 . 2))
(defun fnxx1 (x y) (list (car x) (car y)))
(defun fnxx2 (x y) (list (cdr x) (cdr y)))
(defun fnxx3 (x y) (list x y))
(defun fnxl1 (x) (equal (first x 4)))
(defun vm (x) (eval (print (macroexpand x))))
'(lambda (x) (+ x x))
'(lambda (x) (> x 3))
(defun visuvar (var arg)
`(format t "~% Parametre: ~a = ~a" ',var ,arg)
)
(defmacro visu (fn variables)
(append
`(progn)
(list
`(format t "~%Function: ~a" ',fn)
(if (atom variables)
(visuvar variables variables)
(append `(progn)
(mapcar '(lambda (x) (visuvar
x x)) variables)
)
)
`(format t "~%-*-*-*-*-*-*-*~%")
) ) )
(defun toto (x y) (visu toto (x y))
(vm '(v toto chiffre))
(vm '(v toto (chiffre lettre)))