日下部陽一(void)さんと遊ぼう(6)


# のら猫 『処理系によっては2つの書き方が別なバイナリになる可能性があるとか、
do-while を使えば短くなる場合があるとか、そういうオチだったら萎えますな。』

今回のように、AとBとがequivalent(等価)なコードであると言う場合、それは意味的に同じと言うことである。ここで意味論について深く突っ込む気は無いので簡単にだけ言うと、同じ意味ならば同じ働きをすると考えて良い。同じ働きをするとは言っても生成されるコードは異なるかも知れない。ある働きをするプログラムというのは無数の組み合わせが考えられうるからである。



http://std.dkuug.dk/JTC1/SC22/WG14/www/docs/n843.htm
の6.8.5.3に、forをwhileで書き換える例が載ってますが、その例に
for(;exp;) st を適用すると while (exp) st と等価なのでは?

この私の反論自体は部分的には間違ってはいない。強いて言うなら、forの場合expの部分は省略できると言うことである。言うまでもなく省略時はexpに非0の定数を書いた時と等価である。つまり、この観点から見てもwhileはforで書いても同じ文字数でかつ、whileで永久ループを作りだす場合についてはwhile(1)となるがforで書けばfor(;;)と一文字少なくて済む。つまり、forはwhileと比較して文字数的には何一つ劣っていない。それでは何故、この私の書き込みが大チョンボなのか?


「for(;exp;) st と while (exp) st とは等価」である事実から st に「{ st1 st2 exp2; }」を代入して


while(exp1) { st1 st2 exp2; }

for(;exp1;) { st1 st2 exp2; }
とが等価であることを導ける。


よって、「この二つが等価では無い」と主張する日下部さんへの反論にはなっているように見える。ところが、この二つが等価である事実からは、それゆえ「forがwhileより(文字数において)優れている」とは論理的に結論出来ないのである。


なぜなら、もともとこの話は、


while(exp1){st exp2; }

for(;exp1;exp2) st
と書き換えが利くことが多いのでforが優れていると私が主張したことに端を発する。実際には、whileの場合

while(exp1){st exp2; }
ではなく
while(exp1){st1 st2 }

のようにexp2;の部分にはsentenceを書ける。要するに、whileの本来の記述能力より劣っているものを持ち出してきて、それと等価なものがforだと短く書けるからと言って、forで書けば“必ず”whileと同じ文字数か短くなるというのは論理的に誤りなのである。


そこで、whileを用いたあらゆるコードがforでそれと同じ文字数に収まることを証明することに注力すべきだった。日下部さんの主張は「whileだとforより短くなる場合がある」というものだから、「forで書けばワーストケースにおいてさえもwhileと同じ文字数で書ける」というのを私は優先して証明すべきだった。「forで書けばwhileより短くなることがある」というのは日下部さんの主張を崩すのにはどうでも良いことだったのだ。


日下部さんはさながらモグラ叩きのように叩けるところはすべて叩きにくる。こちらとしてはすべてを反撃する必要はなく、どこか一か所を反撃できれば良い、と思っていたのだが、まんまと乗せられてしまった。


(つづく)