早めの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++に逃げることが多いです。