Scheme における戻り値の未規定

プログラミング言語 Scheme では式を評価することで値が得られる。 そしていくつかの手続きは戻り値が未規定である。 JavaScript などでは「未定義値という値」が存在することと、 Scheme のいくつかの実装でも同様にそのようなオブジェクトが使われていることからしばしば誤解されることがあるようなのだが、 Scheme でいうところの「戻り値が未規定」というのは何も決まっていないという意味である。

未規定なのは処理系の裁量で好きにしていいのだ。 各手続きの処理の中で使えそうな情報を返すような実装でも許されるし、デタラメな数値かもしれないし、とりあえず真偽値でも返しておくというのもかまわない。 実際には REPL で対話的にプログラミングしているときに無関係な出鱈目な値が出てくるのはうんざりするということもあってか、未規定であることを表すオブジェクトを返す処理系は多い。 その他、 '()#f を返すような実装も一般的である。

ちなみに、 R5RS や R7RS では「式の結果は未規定 (the result of the expression is unspecified)」という表現になっているのだが、 R6RS では「未規定値を返す (return unspecified values)」という表現になっている。 私は英語を不得意としているから微妙な意味合いを捉えることが出来ないのだけれども、もし JavaScript などに慣れた人が見たら R6RS は未規定を表すオブジェクトがあるように誤解しやすい表現であるように思う。 一方で、 R5RS や R7RS で用いられている result という語は副作用も含めた結果を連想させてしまうと思う。 言葉の意味するところについて説明している項目はあるのだが、(Scheme の仕様はそう多くもない分量とはいえども) 隅々まで目を通している方が少数派であろうし、知っていても言葉の印象に引き摺られるということはあるかもしれない。

更に、 R6RS で表現が異なっているのは文章表現が異なっているだけではない。 よく見ると values という複数形で書かれているのである。 R6RS で、ある手続きが未規定値を返すといった場合にはそれが多値である可能性がある。 このことは 5.9 Unspecified behavior に明記されている。 実際に多値な実装を見たことはないが、戻り値が未規定の件については R5RS や R7RS より R6RS の方がより未規定というわけだ。

他の言語でもそうだが、仕様で未規定な部分は不意に処理系が挙動を変えてしまったり、処理系ごとに挙動が違ったりする。 意識しておかないと処理系が更新したときに急に動かなくなってしまうこともあるし、移植性に劣るものになってしまうかもしれない。 こういった未規定な値に依存しないように注意が必要だ。

Document ID: a58c1648bb0f2db1ea76d5e7b78a1fa8