多くのWeb記事では、関数型プログラミングは、あらゆる種類の変数の再割り当てを回避し、少なくとも「最終的な」変数のみを促進して、特に読みやすくするものとして提示されています。
それらのほとんどは、カウンター変数が増分する貧弱なループのサンプルです。(有名なi++
またはのようにx = x + 1
。ここにそれを説明するボブおじさんの記事:FPエピソード1
したがって、これらの記事は、可変変数を頼りにすると副作用が発生することが多く、特に「参照透過性」と呼ばれるものを防ぎ、マルチスレッドまたはより優れたマルチプロセッサで実行されるプログラムの構築を困難にすることを示しています。
私の質問は次のとおりです。ご存知のとおり、i++
一般的にスレッドLOCAL変数であるため、並行処理を行っても問題は発生しません。
割り当ての欠点としてローカル変数を使用したループのような例を選択し、並行性プログラミングが危険であると直接結論付けることを許可するのはなぜですか?これらは両方とも私とはまったく関係がありません。
より明確にするために、enemy
Javaのようにロックのすべての定型文を使いすぎずに、明らかに並行プログラミングのグローバル変数(またはフィールドオブジェクト)の再割り当てを選択してください。
このループサンプルは、関数型プログラミングの利点を命令型プログラマーに伝えるための最良の例ではないと本当に思います。
List
さらに、たとえばScalaは.scalaクラスのように多くのwhileループパターンを使用するため、「noob」関数型プログラマーとの混乱を招きます。
override def take(n: Int): List[A] = {
val b = new ListBuffer[A]
var i = 0
var these = this
while (!these.isEmpty && i < n) {
i += 1 // reassignment here
b += these.head
these = these.tail
}
if (these.isEmpty) this
else b.toList
}