多値
Common Lispでは関数は値を0個以上返す.これまでは主に1つの値を返す場合の記述をしてきた.本頁では0個の値を返す,つまり値を返さない場合や2個以上の値を返す場合について記述する.
多値を返す関数としてvaluesがある.
(values 値 値 値...)valuesは引数の値をすべて返す.以下に例を示す.
> (values 1 2 3) 1 ; 2 ; 3このvaluesを関数の最後に実行すれば,多値を返す関数を作成することができる.以下は三つの引数をそのまま返す関数である.
> (defun hoge (a b c) (values a b c)) HOGE > (hoge 1 2 3) 1 ; 2 ; 3
今までのやりかたでは,関数から多値を受け取ることはできない.
> (defun hoge (a b c) (values a b c)) HOGE > (setf x (hoge 1 2 3)) 1 > x 1関数から多値を受け取るにはmultiple-value-bindを使用する.
(multiple-value-bind リスト 多値関数呼び出し 式 式 式...)multiple-value-bindを使用すると,リストに多値関数の返り値が格納される.
> (multiple-value-bind (x y z) (hoge 1 2 3) (format t "~A,~A,~A~%" x y z)) 1,2,3 NIL > x *** - EVAL: variable X has no valueここで,x,y,zはmultiple-value-bind式内でのみ有効であることに注意する.multiple-value-bindの第一引数のリストの要素数が多値関数の返り値の数より少なければ,足りない分は単に捨てられる.
> (multiple-value-bind (x y) (hoge 1 2 3) (format t "~A,~A~%" x y)) 1,2 NIL逆にmultiple-value-bindの第一引数のリストの要素数が多値関数の返り値の数より多ければ,多い分にはNILが格納される.
> (multiple-value-bind (x y z aa) (hoge 1 2 3) (format t "~A,~A,~A,~A~%" x y z aa)) 1,2,3,NIL NILmultiple-value-bindの返り値は,最後に実行された式の値である.
> (multiple-value-bind (x y z) (hoge 1 2 3) 'a) A > (multiple-value-bind (x y z) (hoge 1 2 3) 'a 'b) B
multiple-value-callを使用すると,多値を関数の引数に渡すことができる.
(multiple-value-call 関数 多値関数)以下はhogeから返る多値をfugaに渡す例である.
> (defun fuga (x y z) (values x y z (+ x y z))) FUGA > (multiple-value-call #'fuga (hoge 1 2 3)) 1 ; 2 ; 3 ; 6
(multiple-value-call #'list 多値関数)と同等のものとして
(multiple-value-list 多値関数)がある.
> (multiple-value-call #'list (hoge 1 2 3)) (1 2 3) > (multiple-value-list (hoge 1 2 3)) (1 2 3)multiple-value-listは多値関数の返り値をリスト化することが比較的多いことから作成されたのだと思う.