早めのreturn
例えば、C言語で
int foo()
{
int ret;
if (bar()) {
/* (行数的に)短い処理 */
ret = 1;
}
else {
/* (行数的に)長い処理 */
ret = 0;
}
return ret;
}
こんな風な書き方をする人と、
int foo()
{
if (bar()) {
/* 短い処理 */
return 1;
}
/* 長い処理 */
return 0;
}
こんな風な書き方をする人、どちらが多いんでしょうか。
私は早めにreturnで関数を抜ける方が読み易いし、
長い処理のネストが一段浅くなるので、後者の方を好んで使いますが、
一部業界では「関数にreturnは1個しか書けない」という謎の規約があるため、
前者のような書き方を強要されるそうです。
Common Lispでも同様に
(defun foo ()
(cond ((bar)
;短い処理
1)
(t
;長い処理
0)));
のような書き方をするか、
(defun foo ()
(when (bar)
;短い処理
(return-from foo 1))
;長い処理
0)
のような書き方をするか選べます。私はこれも後者を好んで使います。
けど、Lispの入門書ではこのようにreturn-fromを使ってるのをあまり見ない気がします。
Schemeだとreturnがないのでcall/ccを使うことになります。
(define (foo)
(call/cc
(lambda (ret)
(if (bar)
(begin
;短い処理
(ret 1)))
;長い処理
0)))
ただ、この書き方だと結局ネストが深くなってしまうので、
引数として継続を受け取った方が自然かもしれません。
(define (foo ret)
(if (bar)
(begin
;短い処理
(ret 1)))
;長い処理
0)
(call/cc foo)
Schemeのcall/ccを利用した早めのreturnも好きなんですが、
その目的のためだけにcall/ccはちょっと重たいかもしれません。
脱出専用なので、処理系がどうにかして効率のいい実行をしてくれないのかな。
私の会社ではreturn1つです。さらに出向かい先ではバラバラです。do, while(0)で囲んでretにエラーコード入れて途中でbreakで抜けたりすることも。LispやSchemeの場合規約はあるんでしょか
> do, while(0)で囲んでretにエラーコード入れて途中でbreakで抜けたり
やっぱり、苦労されてるんですね。
ちょっと違う話ですが、
PostScriptにはswitch-caseに相当する構文がなく、
if-elseで書くとネストが非常に深くなるので、
loopの中でifを書いてbreakした覚えがあります。
> LispやSchemeの場合規約はあるんでしょか
それは仕事でLispを書いてる人に聞いてみないと分かりません(笑)
途中returnはfreeとかのし忘れが怖いので、自分はreturnの代わりにgoto文で関数の最後に飛ばすかC++に逃げることが多いです。