Em Common Lisp, uma função não só pode devolver um valor, como pode devolver vários valores. Por exemplo, floor, que arredonda para baixo em direção ao zero, devolve dois valores: o primeiro é o valor arredondado e o segundo é o resto.
(floor 3.5) ; => 3
; 0.5
(Vamos mostrar os vários valores devolvidos em linhas separadas da saída.)
Se quiseres que uma função devolva vários valores, usas o acessor values:
(defun three-numbers () (values 1 2 3))
(three-numbers) ; => 1
; 2
; 3
Se tiveres uma lista de valores que queres devolver, podes usar value-list:
(values-list '(a b c)) ; => a
; b
; c
Se só te interessa o primeiro valor, não precisas de fazer nada de especial. A linguagem trata disso por ti:
(+ (values 1 2 3) (values 10 20 30)) ; => 11
No entanto, se quiseres aceder aos outros valores, há várias funções que precisas de usar.
Há duas macros principais: multiple-value-list e multiple-value-bind.
Servem para envolver algo que devolve vários valores e capturar todos esses valores.
A primeira cria uma lista com todos os valores.
A segunda permite-te associar variáveis aos valores individuais.
(multiple-value-list (values 1 2 3)) ; => (1 2 3)
(multiple-value-bind (a b c) (values 1 2 3)
(+ a b c)) ; => 6
Repara que as variáveis a, b e c só estão no âmbito dentro de multiple-values-bind.
Outra macro útil é nth-value. Tal como nth para listas, devolve o item "nth" de um conjunto de vários valores:
(nth-value 0 (values 1 2 3 )) ; => 1
(nth-value 1 (values 1 2 3 )) ; => 2
(nth-value 2 (values 1 2 3 )) ; => 3