これは興味深い議論です。@flodelの例は素晴らしいと思います。ただし、関数型コーディングスタイルではなく命令型return
を使用する場合に意味がある私のポイント(および@koshkeがコメントでこれを言及している)を示していると思います。
重要なことではありませんが、私は次のように書き直したでしょうfoo
。
foo = function() ifelse(a,a,b)
関数スタイルは、の値の保存など、状態の変更を回避しますoutput
。このスタイルでreturn
は、場違いです。foo
数学関数のように見えます。
私は@flodelに同意する:にブール変数の複雑なシステムを使用してbar
、あなたが持っているときあまり明確で、かつ無意味だろうreturn
。何がbar
にとても適しreturn
文は、それが不可欠なスタイルで書かれていることです。実際、ブール変数は、関数スタイルで回避された「状態」の変化を表しています。
bar
単なる擬似コードであるため、関数形式で書き直すのは本当に難しいですが、アイデアは次のようなものです。
e_func <- function() do_stuff
d_func <- function() ifelse(any(sapply(seq(d),e_func)),2,3)
b_func <- function() {
do_stuff
ifelse(c,1,sapply(seq(b),d_func))
}
bar <- function () {
do_stuff
sapply(seq(a),b_func) # Not exactly correct, but illustrates the idea.
}
while
それが状態変化によって制御されているので、ループは、書き換えが最も困難であろうa
。
への呼び出しによる速度の低下return
は無視できますが、return
関数形式での回避と書き換えによって得られる効率は、非常に大きなものになることがよくあります。新しいユーザーに使用をやめるように言ってreturn
も役に立たないかもしれませんが、機能的なスタイルに誘導することには効果があります。
@Paul return
は、ループ内のさまざまなポイントで関数を終了することがよくあるため、命令スタイルで必要です。関数スタイルはループを使用しないため、を必要としませんreturn
。純粋に機能的なスタイルでは、最後の呼び出しはほとんど常に目的の戻り値です。
Pythonでは、関数にはreturn
ステートメントが必要です。ただし、関数スタイルで関数をプログラミングした場合は、関数return
の最後にステートメントが1つしかありません。
別のStackOverflow投稿の例を使用TRUE
して、指定されたすべての値のx
長さが奇数である場合に返される関数が必要だとしましょう。2つのスタイルを使用できます。
# Procedural / Imperative
allOdd = function(x) {
for (i in x) if (length(i) %% 2 == 0) return (FALSE)
return (TRUE)
}
# Functional
allOdd = function(x)
all(length(x) %% 2 == 1)
関数形式では、返される値は当然関数の最後にあります。繰り返しますが、それは数学関数のように見えます。
@GSeeで説明されて?ifelse
いる警告は間違いなく興味深いものですが、関数の使用をやめさせようとしているとは思いません。実際にifelse
は、関数を自動的にベクトル化するという利点があります。たとえば、少し変更したバージョンを考えてみfoo
ます。
foo = function(a) { # Note that it now has an argument
if(a) {
return(a)
} else {
return(b)
}
}
この関数length(a)
は、1の場合に正常に機能します。ただしfoo
、ifelse
foo = function (a) ifelse(a,a,b)
今foo
の任意の長さで動作しますa
。実際、a
が行列の場合でも機能します。test
ベクトル化に役立つ機能と同じ形状の値を返すことは問題ではありません。
return
最後の例でも不要です。削除return
すると少し速くなるかもしれませんが、私の考えでは、これはRが機能的なプログラミング言語であると言われているためです。