多値と関数合成
PLT Scheme のレファレンス・マニュアルを読んでいてちょっと驚いたことがあるので書きます。
compose 関数で合成する関数の中に、多値を返す関数を入れられるんですよ:
(map (compose list split-path path->complete-path) (directory-list)) ; => ((#<path:C:\home\desktop\> #<path:onlisp.pdf> #f) ...)
(split-path が多値を返す関数です)
もしかして Scheme では普通なんでしょうか?
どうやっているのか気になって、compose の定義 (collects/scheme/private/list.ss 内) を調べてみると
(compose f g)
とある時に、f の引数の数を procedure-arity という関数で調べ、それが 1 でない場合は call-with-values で g の適用結果を f に渡す、ということをしていました:
(call-with-values (lambda () (g a)) f)
なるほどなという感じです。
でも、関数の引数の数は分かるとしても、返り値の数までは知り得ないですよね? もし g が多値を返さない関数でも call-with-values を使って良いんでしょうか?
(call-with-values (lambda () 1) list) ; => (1)
あ、1値でも使えるんですね。知らなかったです。