有意な値を返さない - lisp-cookbook-ja/common-lisp GitHub Wiki

制御構造

有意な値を返さないことを示すイディオムとしては、valuesを利用するものがあり、

(values)

のように書かれます。 これは、0個の多値を返すことを示します。

(defun hello ()
  (format t "こんにちは!!~%")
  (values))

(hello)
;-> こんにちは!!
;=> No values

参考

0個の返り値は、フォームの用いられる場所によっては値がnilとして扱われます。

(if (values) "はい" "いいえ")
;=> "いいえ"

(or (values) (values) (values))
;=> No values
(or (values) (values) (values 1))
;=> 1

議論

  • 「0個の返り値は〜nilとして扱われます」というのは、単に 「期待されている値より少ない値が返ってきた場合、足りない値はnilとして扱う」 という一般的なルールの1インスタンスにすぎないのでは。

(multiple-value-bind (a b c d e) (values 1)
  (list a b c d e))
;=> (1 NIL NIL NIL NIL)

(multiple-value-bind (a b c d e) (values)
  (list a b c d e))
;=> (NIL NIL NIL NIL NIL)

というところですね。 確かにその方が統一的で綺麗ですし、「0個の返り値は〜nilとして扱われます」と書いたのは曖昧な含みがあるかと思いました。 ただ、3.1.7 Return Valuesを参照すると0個の多値の扱われ方については親切に解説しているのですが、「期待されている値より少ない値が返ってきた場合、足りない値はnilとして扱う」という取り決めからの帰結かどうかは確認できなかったので、インスタンス的な解説個所をそのまま引いて来た感じになりました。自分の解釈では、「受取側は必ず1つ以上の返り値を期待していて、0個の場合はnilになる」のかなと思えました。

(values (values))
;=> NIL

等。また、multiple-value-bind等でも、足りない場合にどうするかはインスタンスの事例的に書かれているように思われました。 個人的には、「期待されている値より少ない値が返ってきた場合、足りない値はnilとして扱う」の記述がどこかにあっても良いような気がしますし、確認できたら記載したいと思います。 どちらかというと、「(values)は有意な値を返さないイディオムなんですが、(values)自体はNILとして扱われてしまいますよー」ということが記述の意図だったのですが、追及すると深いので曖昧にしてしまいました。 また、関連してですが、CLとSchemeでの未定義値的な扱いの違いについて別項目を立てるのも有意義かなと思いました(CLでは実際のところNILになってしまいますが…) --g000001