في Common Lisp، لا تقتصر الدالة على إرجاع قيمة واحدة فقط، بل يمكنها أن تُرجع قيمًا متعددة. على سبيل المثال، الدالة floor التي تُقرّب نحو الصفر تُرجع قيمتين: الأولى هي القيمة المقرَّبة، والثانية هي الباقي.
(floor 3.5) ; => 3
; 0.5
(سنعرض القيم المتعددة المُرجعة على أسطر منفصلة في المخرجات.)
إذا أردت أن تُرجع الدالة قيمًا متعددة، فاستخدم الدالة values:
(defun three-numbers () (values 1 2 3))
(three-numbers) ; => 1
; 2
; 3
إذا كانت لديك قائمة قيم تريد إرجاعها، فيمكنك استخدام value-list:
(values-list '(a b c)) ; => a
; b
; c
إذا كنت تهتم بالقيمة الأولى فقط، فلا حاجة إلى أي إجراء خاص، فاللغة تتولى ذلك:
(+ (values 1 2 3) (values 10 20 30)) ; => 11
لكن إذا أردت الوصول إلى تلك القيم الأخرى، فهناك عدة دوال ستحتاج إلى استخدامها.
هناك ماكروان رئيسيان هما multiple-value-list وmultiple-value-bind.
يُستخدم هذان الماكروان لتغليف شيء يُرجع قيمًا متعددة والتقاط كل هذه القيم.
الأول يُنشئ قائمة بكل القيم.
والثاني يتيح لك ربط المتغيرات بكل قيمة على حدة.
(multiple-value-list (values 1 2 3)) ; => (1 2 3)
(multiple-value-bind (a b c) (values 1 2 3)
(+ a b c)) ; => 6
لاحظ أن المتغيرات a وb وc لا تكون في النطاق إلا داخل multiple-values-bind.
وهناك ماكرو آخر مفيد هو nth-value. وهو يشبه nth مع القوائم، إذ يُرجع العنصر النوني من مجموعة من القيم المتعددة:
(nth-value 0 (values 1 2 3 )) ; => 1
(nth-value 1 (values 1 2 3 )) ; => 2
(nth-value 2 (values 1 2 3 )) ; => 3