LES TYPES:
(defun foo (x)
(declare (type float x))
(format t "Voici un nombre flottant: ~a." x)
'fin)
FOO définit une fonction contenant une déclaration de type
l'argument de foo doit être un nombre flottant
(foo pi)
Voici un nombre flottant: 3.141592653589793d0.
FIN pi est bien un nombre flottant
(foo 3/2)
; Evaluation aborted on #
(type-of s)
ESSAI S est du type ESSAI (ESSAI étant précédemment définit comme une structure)
(type-of 3)
(INTEGER 0 536870911) 3 est un entier
(type-of #C(3 2))
(COMPLEX (INTEGER 2 3)) #C(3 2) est un nombre complexe et les parties réelles et imaginaires sont des entiers.
(type-of #C(3 2.0))
(COMPLEX (SINGLE-FLOAT 2.0 3.0)) #C(3 2.0) est un nombre complexe et les parties réelles (après conversion) et imaginaires sont des flottants simples.
(type-of 2/3)
RATIO 2/3 est un rationnel non entier
RATIO est un type propre au langage LISP qui permet de donner un résultat sous sa forme exacte
Donc TYPE-OF rend le type de l'objet passé en argument.
TYPEP:
(typep *x* 'array)
T rend vrai car *x* a été défini comme un tableau précédemment
noter le quote ' devant array, sinon array est pris comme une variable, d'où: erreur
rend NIL si *x* n'est pas un tableau
Suivant le cas, pour contrôler le type on utilise les mots (quotés) suivants:
array float package sequence bit-vector function
pathname short-float character hash-table random-state single-float
complex integer ratio stream condition long-float
rational string cons null readtable symbol double-float
number restart vector fixnum t
LES FERMETURES:
Quelques exemples:
(let ((a 0))
(defun compte ()
(format t "a = ~a~%" (incf a)))
(defun réinitialisation (&optional (néo-a 0))
(setf a néo-a)
(format t "a = ~a~%" a)))
RÉINITIALISATION a est une variable locale et les fonctions compte et réinitialisation sont des fermetures car définies dans un LET. la variable locale est évidemment inaccessible.
(compte)
a = 1
NIL au 1er appel à compte, A est incrémenté et le résultat affiché
(compte)
a = 2
NIL idem
(réinitialisation -1)
a = -1
NIL à l'appel de la fonction réinitialisation, la valeur optionnelle de a est -1 (0 par défaut),
valeur ensuite affichée
(compte)
a = 0
NIL à l'appel de compte, a est incrémenté avant d'être affiché
__________________________________________________________________________
Exemple d'utilisation de fermetures pour montrer le fonctionnement de BLOCK et RETURN-FROM:
(defparameter a 0) a doit être définie lors de l'appel à la fonction anonyme invoquée par
FUNCALL dans ce qui suit:
(let ((a 0))
(format t "Entrée dans LET~%")
(defun compte () ;1ère fermeture (utilisée pour incrémenter a)
(format t "a = ~a~%" (incf a)))
(defun réinitialisation (&optional (néo-a 0)) ;2ème fermeture (pour réinitialiser a)
(setf a néo-a)
(format t "a = ~a~%" a))
(defun foo () ;3ème fermeture pour voir les blocs
(if (> a 4) (réinitialisation)) ;a repasse à 0 si a>4
(format t " Entrée dans FOO~%")
(block k ;un bloc k dans la fonction foo
(format t " Entrée dans le bloc k~%")
(bar #'(lambda () (if (= a 3) (progn (format t " Sortie conditionnelle du bloc k~%") (return-from k)))))
(format t " Sortie du bloc k~%"))
(format t " Sortie de FOO~%")
(compte))
(format t "Sortie du LET~%"))
(defun bar (fn) ;cette fonction est appelée dans la fermeture foo
(format t " Entrée dans BAR~%")
(block l ;un bloc l dans la fonction bar
(format t " Entrée dans le bloc l~%")
(baz #'(lambda () (if (= a 2)
(progn (format t " Sortie conditionnelle du bloc l~%") (return-from l))
(funcall fn)))) ;invocation de lambda (fn) par FUNCALL, si a différent de 2
(format t " Sortie du bloc l~%"))
(format t " Sortie de BAR~%"))
(defun baz (fn) ;cette fonction est appelée dans la fonction bar
(format t " Entrée dans BAZ~%")
(block m ;un bloc m dans la fonction baz
(format t " Entrée dans le bloc m~%")
(funcall fn) ;invocation inconditionnelle de lambda (fn) par FUNCALL
(format t " Sortie du bloc m~%"))
(format t " Sortie de BAZ~%"))
Pour a = 3, on obtient à l'appel de foo (en utilisant réinitialisation et compte préalablement):
(foo)
Entrée dans FOO
Entrée dans le bloc k
Entrée dans BAR
Entrée dans le bloc l
Entrée dans BAZ
Entrée dans le bloc m
Sortie conditionnelle du bloc k on voit, ici, que BAR, bloc l, BAZ et bloc m sortent, également, de la pile
Sortie de FOO
NIL
________________________________________________________________________________________________________________________
DOCUMENTATION: sur les fonctions et les variables.
(defun la-fonction (x)
"rend le carré du nombre passé en argument" ;documentation sur la fonction
(if (numberp x)
(print (* x x))
"L'argument doit être un nombre"))
LA-FONCTION
(defvar *la-variable* 15 "Une variable globale")
*LA-VARIABLE* définition d'une variable globale avec documentation
(apropos 'la-)
*LA-VARIABLE* (bound)
LA-
LA-FONCTION (fbound)
SB-IMPL::VANILLA-OPEN-ERROR
; No value donne des indications sur les variables et fonctions commençants par la-
(documentation 'la-fonction 'function)
"rend le carré du nombre passé en argument" rend la documentation de la-fonction
(documentation '*la-variable* 'variable)
"Une variable globale" rend la documentation de *la-variable*
Le 2ème argument (quoté) passé à DOCUMENTATION peut être function, variable, structure, type, setf et T.
Pour connaître la documentation de plusieurs fonctions contenue dans une liste:
(dolist (x '(cons car cdr)) (print x) (print (documentation x 'function)))
CONS
"Return a list with SE1 as the CAR and SE2 as the CDR."
CAR
"Return the 1st object in a list."
CDR
"Return all but the first object in a list."
NIL
DESCRIBE:
(describe 'la-fonction)
COMMON-LISP-USER::LA-FONCTION
[symbol]
LA-FONCTION names a compiled function:
Lambda-list: (X)
Derived type: (FUNCTION (T)
(VALUES (OR NUMBER (SIMPLE-ARRAY CHARACTER (30)))
&OPTIONAL))
Documentation:
rend le carré du nombre passé en argument
Source form:
(SB-INT:NAMED-LAMBDA LA-FONCTION
(X)
(BLOCK LA-FONCTION
(IF (NUMBERP X)
(PRINT (* X X))
"L'argument doit être un nombre")))
rend une description de la fonction et de toutes les informations associées
INSPECT: pour inspecter les propriétés d'un objet.
(inspect 'car)
The object is a SYMBOL.
0. Name: "CAR"
1. Package: #
2. Value: "unbound"
3. Function: #
4. Plist: NIL
> 0 ici, on demande des renseignements sur le nom
The object is a VECTOR of length 3.
0. #\C
1. #\A
2. #\R
> 1
The object is an ATOM:
#\A
> q on quitte INSPECT
; No value
Voici quelques raccourcis utiles, sous SLIME, liés à la documentation sur un symbole:
Placer le curseur sur le symbole d'abord, puis:
C-c C-d d donne la même chose que DESCRIBE et l'affiche dans un tampon (EMACS).
C-c C-D f décrit la fonction dans un tampon.
C-c C-d h ouvre l'hyperspec dans un navigateur à la page correspondant au symbole.
C-c C-d a recherche un apropos concernant le terme demandé dans le mini-buffer.
C-c I lance SLIME inspector. Entrer l'expression à inspecter (ex: (fac 5)), et valider.
se déplacer sur l'objet à détailler et valider. l pour revenir en arrière.
q pour quitter l'inspecteur.
Prochainement: LES SYMBOLES.
Aucun commentaire:
Enregistrer un commentaire