檜山さんが returnも嫌いな理由 という興味深いエントリを書かれている。

結論自体はまったく異論はないのだけど、どうにももやもやしたものを抱えていた。ついさっき、その正体が分かった気がしたので駄文ながらぐだぐだと書いてみる。

以下、続きを読む。からどうぞ


ウルトラマン
リターン議論! ランキング!

つまり、僕は檜山さんの意見じゃなくてメイヤーセンセのごイケンに賛成できないものを感じていたのね。


1.return 変数という形を使うとき、この変数は、計算の中間結果を保持するためにだけ存在している。
2.return文をあっちこっちに散りばめた、複数の出口を持つ関数が作られやすい。
3.関数が実行した最後の文がreturn文でないとき、関数の戻り値が何であるべきか定義する必要がある。



これは実は1つも賛成できない。

まず1なんだけども、変数Resultを使うってことは関数最後尾にC言語風にいうところの
return Result;
って行を挿入することに等しい。
でも、これってResultってだけじゃ何も意味をもっていなくて
return tmp;
って書いたのと情報量は変わらない。
僕は名前重要!主義者なのだからして、tmp だの val1 だのって変数は大嫌い。一例を挙げよう

かの有名なprintfの型宣言はこう

 int printf(const char *format, ...); 


でもこの戻り値ってつかったことある人ってまずいないよね?
で、何かの拍子にこの戻り値を調べたくなったとする。で関数の実装を見るわけだ

ここで

 
va_start(arg, format);
result = vfprintf(stdout, format, arg);
va_end(arg);

return result;
}


 
va_start(arg, format);
num_output_bytes = vfprintf(stdout, format, arg);
va_end(arg);

return num_output_bytes;
}


はたして、どちらが情報量が多いだろうか?


ここからチラシの裏。
ところで、今のプログラミング言語ってたいてい関数宣言に引数名いれますわな。
型チェック的にはまるで必要ないけど、わかりやすさのために。
なんで、戻り値はだれも名前をつけようとせんのだろう?



2.についても、積極的に複数出口推進派として全否定したい。

いや、あれですよ
「必要以上に」むやみやたらに出口が多いプログラミングはあかんとは僕も思いますよ。
でもたくさんがアカンから出口は1つが一番だ!ってのは、かなり飛躍があるでしょ。
ぶっちゃけ、ただの思い込みなんじゃないの? と。

たとえば

 
function calcTotal(numarray, n) {
var total = 0;
if (numarray != null) {
for (var i = 0; i < min(n, numarray.length); i++) {
total += numarray[i];
}
}
return total; // 1
}


というプログラムで、おかしな引数はわたしてないつもりなのになぜか0が帰る時があるとする
(もちろん、つもりってのが気のせいで呼び方が間違っているんだが)

そうするとこのプログラムだと return tolal; の行に total==0 の条件ブレークを貼らないといけない。
gdb とかでデバッグしてて条件ブレーク入れたら実行がやたら遅くなった。という経験を持つ人は多いと思うがインタプリタ言語はともかくとして、コンパイル型言語だと条件ブレークってのは普通に無条件ブレーク命令をプログラム中に埋め込んでおいて、ブレークして止まったときにユーザに見せる前にまず条件式を評価、式が真にならなかったら、ユーザープロンプトに戻らず自動的に実行を再開。ということをデバッガがこっそり実行しているだけなのだ。
そんなぼんぼんCPU例外起こしといて速度なんか出るわけないでしょ。
そういうわけで、運が良くて超遅くてイライラ。運が悪いと速度が遅くなった影響でどこかでtimeoutが動き出して
デバッグがそもそも不可能になってしまう。

デバッグを軽視しているコーディングスタイルってどうなのさ?
とか思いませんか。

職業プログラマーだと、自分がバグ0でもどこかのアホが1人でもちょんぼしたらデバッグは付き合わされるわけで。
(とゆーか、会社でそれなりのポジションにつけば、後輩のデバッグに付き合わされる時間がどんどん延びていくよね)


3.はホント?
C言語は、returnがなかったときの動作は未定義だけど、これが原因のバグって聞かないよ。
なぜならコンパイラが検出して warning だしてくれるから。
逆に perl のような最終評価結果をreturn値とする言語のほうがうっかり動いてしまって
デバッガ動かさないと原因がわからなくてイヤな思いすることが多いけどなぁ・・


という事で、オイラはラムダ式以外では最終評価結果を返す仕様はあんまり好きじゃないなぁ・・・
あ、ラムダはいいんですよ。ラムダ式で if だの switch だのがわらわら出てくるのは違う意味で
論外なので、まぎらわしいケースにまず出会わないから。

どうでしょ?