In Common Lisp una funzione non solo può restituire un valore, ma può restituirne più di uno.
Per esempio floor, che arrotonda verso il basso in direzione dello zero, restituisce due valori: il primo è il valore arrotondato, il secondo è il resto.
(floor 3.5) ; => 3
; 0.5
(Mostreremo i valori restituiti su righe separate dell'output.)
Se vuoi che una funzione restituisca più valori, usa la funzione di accesso values:
(defun three-numbers () (values 1 2 3))
(three-numbers) ; => 1
; 2
; 3
Se hai un array di valori che vuoi restituire, puoi usare value-list:
(values-list '(a b c)) ; => a
; b
; c
Se ti interessa solo il primo valore, non devi fare nulla di speciale: ci pensa il linguaggio:
(+ (values 1 2 3) (values 10 20 30)) ; => 11
Se invece vuoi accedere a quegli altri valori, dovrai usare diverse funzioni.
Le due macro principali sono multiple-value-list e multiple-value-bind.
Servono a racchiudere qualcosa che restituisce più valori e a catturarli tutti.
La prima crea un array con tutti i valori.
La seconda ti permette di associare le variabili ai singoli valori.
(multiple-value-list (values 1 2 3)) ; => (1 2 3)
(multiple-value-bind (a b c) (values 1 2 3)
(+ a b c)) ; => 6
Nota che le variabili a, b e c sono nello scope solo all'interno di multiple-values-bind.
Un'altra macro utile è nth-value. È come nth per gli array: restituisce l'elemento «nth» da un insieme di più valori:
(nth-value 0 (values 1 2 3 )) ; => 1
(nth-value 1 (values 1 2 3 )) ; => 2
(nth-value 2 (values 1 2 3 )) ; => 3