En Common Lisp, une fonction peut non seulement renvoyer une seule valeur, mais aussi en renvoyer plusieurs.
Par exemple floor, qui arrondit vers le bas en direction de zéro, renvoie deux valeurs : la première est la valeur arrondie et la seconde, le reste.
(floor 3.5) ; => 3
; 0.5
(Nous afficherons les valeurs multiples renvoyées sur des lignes distinctes de la sortie.)
Si tu veux qu'une fonction renvoie plusieurs valeurs, utilise l'accesseur values :
(defun three-numbers () (values 1 2 3))
(three-numbers) ; => 1
; 2
; 3
Si tu as une liste de valeurs à renvoyer, tu peux utiliser value-list :
(values-list '(a b c)) ; => a
; b
; c
Si seule la première valeur t'intéresse, tu n'as rien de spécial à faire, le langage s'en occupe :
(+ (values 1 2 3) (values 10 20 30)) ; => 11
En revanche, si tu veux accéder aux autres valeurs, plusieurs fonctions te seront nécessaires.
Les deux macros principales sont multiple-value-list et multiple-value-bind.
Elles servent à englober une expression qui renvoie plusieurs valeurs et à les capturer toutes.
La première crée une liste de toutes les valeurs.
La seconde te permet de lier des variables à chacune des valeurs.
(multiple-value-list (values 1 2 3)) ; => (1 2 3)
(multiple-value-bind (a b c) (values 1 2 3)
(+ a b c)) ; => 6
Note que les variables a, b et c n'ont de portée qu'à l'intérieur de multiple-values-bind.
Une autre macro utile est nth-value. Elle est comme nth pour les listes : elle renvoie l'élément « nth » d'un ensemble de valeurs multiples :
(nth-value 0 (values 1 2 3 )) ; => 1
(nth-value 1 (values 1 2 3 )) ; => 2
(nth-value 2 (values 1 2 3 )) ; => 3