Scheme言語の手続き呼び出し、評価順序
Scheme言語では手続き呼び出しの評価順序は決まっていません。それがどのように仕様に表現されているのかを確認してみます。
正直右からでも左からでもどちらからでも評価して構わない、というようなフワっとしたことが記述されているのかな、と想像していたのだけれども、それでは仕様として役に立ちませんね。
ただ実際読んだ時、その意味するところがよくわかりませんでした。自分の思考を整理するために、何がわからなかったかというのをよくよく考えてみると、なぜ仕様で順序が不定であるとするのか?がわからない、ということだったのだと思います。
以下に引用します。
4.1.3. Procedure calls
...
The operator and operand expressions are evaluated (in an unspecified order) and the resulting procedure is passed the resulting arguments.
...
Note: In contrast to other dialects of Lisp, the order of evaluation is unspecified, and the operator expression and the operand expressions are always evaluated with the same evaluation rules.
Note: Although the order of evaluation is otherwise unspecified, the effect of any concurrent evaluation of the operator and operand expressions is constrained to be consistent with some sequential order of evaluation. The order of evaluation may be chosen differently for each procedure call.
— Richard Kelsey, William Clinger, And Jonathan Rees (Editors)
日本語訳、助かります!
手続き呼び出し
...
オペレータの式とオペランドの式は(不定の順序で)評価され、評価結果の手続きに評価結果の引数が渡される。
...
注: その他のLisp方言とは対照的に評価の順序は不定であり、オペレータ式とオペランド式は、必ず同一評価規則で評価される。
注: 一般には評価の順序は不定であるが、オペレータ式とオペランド式のいかなる同時並行的評価の結果も、一定の順次的評価と一致しなければならない。評価の順序は手続きの呼び出しごとに選択できる。
— RICHARD KELSEY、WILLIAM CLINGER、JONATHAN REES (編集)…20 february 1998 (犬飼 大訳: 7 May 1999)
このように、不定である、ということしか書いてありません。順序くらい書いておいてくれても、とか、右からでも左かもでも良い、くらいは具体的に記述があるかしらん、と思っていた向きには、びっくりして立ち往生してしまいます。
で、このメールを見て、納得しました。つまり、例えばテスト中にヒューリスティックに評価順序を探るってことすらオッケー、それくらい手続き呼び出しのオペレータ、オペランドの評価順序は不定であって、最適化を妨げるものではない、ということなのだろう、と。
Way back when there was a test system that I used that used a random number generator to choose execution order at every call. The idea was to help one heuristically find unintended order of execution dependences during testing.
納得した上で立ち返ってみると、そもそも評価の順序に関しての注記に書いてあります。
同時並列に評価しても良いし、はたまた、呼び出し毎に評価の順序を変えても良い、それくらいに順序は不定です、ただし。順序付けて評価した結果と一致しなければならない。
あらためて読み返してみると、Scheme言語処理系を実装する向きには挑戦的な記述ですらあるのではないのかな、というのが感想。