他の多くの回答は、関数型プログラミングのパフォーマンス(並列処理)の側面に焦点を当てています。これは非常に重要であると私は信じています。ただし、生産性について具体的に質問しました。たとえば、命令型パラダイムよりも関数型パラダイムの方が同じことをより速くプログラムできますか。
私は実際に(個人的な経験から)F#でのプログラミングが私がよりよく考える方法と一致していることを発見したので、それはより簡単です。それが最大の違いだと思います。私はF#とC#の両方でプログラミングしましたが、F#では「言語との戦い」がはるかに少なくなっています。F#の詳細について考える必要はありません。これが私が本当に楽しんでいると私が見つけたもののいくつかの例です。
たとえば、F#は静的に型指定されていますが(すべての型はコンパイル時に解決されます)、型推論は使用している型を判断するため、言う必要はありません。そしてそれが理解できない場合、それは自動的にあなたの関数/クラス/何でも一般的なものにします。したがって、ジェネリックを記述する必要はありません。すべて自動です。つまり、問題について考えることに多くの時間を費やし、それを実装する方法が少なくなっていることを意味します。実際、C#に戻ると、この型推論が本当に見逃されていることに気付きます。もう必要がなくなるまで、それがどれほど気が散るのかはわかりません。
また、F#では、ループを作成する代わりに、関数を呼び出します。これは微妙な変更ですが、ループ構造について考える必要がなくなったため、重要です。たとえば、これは何かを通過して一致するコードの一部です(私は何を思い出せません、それはプロジェクトオイラーパズルからのものです):
let matchingFactors =
factors
|> Seq.filter (fun x -> largestPalindrome % x = 0)
|> Seq.map (fun x -> (x, largestPalindrome / x))
C#でフィルターを実行してからマップ(各要素の変換)を実行するのは非常に簡単だと思いますが、より低いレベルで考える必要があります。特に、ループ自体を記述し、独自の明示的なifステートメントなどを用意する必要があります。F#を学んでから、機能的な方法でコーディングする方が簡単であることに気付きました。フィルタリングする場合は「filter」を記述し、マップする場合は実装する代わりに「map」を記述します。それぞれの詳細。
また、F#をocaml、そしておそらく他の関数型言語から分離していると思う|>演算子も大好きです。これはパイプ演算子であり、ある式の出力を別の式の入力に「パイプ」することができます。それはコードを私がもっと考える方法に従わせます。上記のコードスニペットのように、「ファクターシーケンスを取得し、フィルター処理してから、マップする」ということです。これは非常に高度な考え方であり、ループやifステートメントの記述に忙しいため、命令型プログラミング言語では理解できません。それは私が他の言語に行くときはいつも私が最も恋しいことの一つです。
したがって、一般的には、C#とF#の両方でプログラミングできますが、より高いレベルで考えることができるため、F#の方が使いやすいと思います。関数型プログラミング(少なくともF#では)から細部が削除されているため、生産性が向上していると私は主張します。
編集:関数型プログラミング言語での「状態」の例を求めたコメントの1つを見ました。F#は必須に記述できるため、F#で変更可能な状態を設定する方法の直接的な例を次に示します。
let mutable x = 5
for i in 1..10 do
x <- x + i