関数型プログラミング言語を使用するのはいつですか?


90

C ++、C#、Javaなどのより冗長なオブジェクト指向言語よりも関数型プログラミング言語を使用することを選択する必要があるのはどのような状況ですか?

関数型プログラミングとは何かを理解していますが、実際には理解していないのは、どのような種類の問題に対して完璧な解決策であるかということです。


この質問は、ここで回答されstackoverflow.com/questions/381685/...
krosenvold

2
常に。または少なくとも決して決して。
シェルビームーアIII

1
ラムダの場合、C#は境界線機能です。
JD 2012年

回答:


50

関数型言語は、私の意見では、主に2つのことに適しています。ゲームAIと数学的計算です。それは、その優れたリスト操作(少なくともLispとScheme)のためにゲームAIに、そしてその構文のために数学的計算に適しています。Scheme、Lisp、Haskellには、数学的な計算を読みやすくする構文があります。最後に付け加えなければならないのは、関数型言語は本当に楽しい言語だということです。私のSchemeコースは、私が最も楽しんだコースの1つでした。


2
スキームで受講したコンパイラクラスの最初の週に脳が爆発したいという事実を乗り越えた後、それはとても楽しいことにも
気づき

1
数学計算に使用した関数型言語はどれですか?
ジュール

8
また、コンパイラ!Haskellでコンパイラを書いたことがある人は、「命令型言語でコンパイラを書くことは二度とない」と言っているのを聞いたことがあります。
ShreevatsaR

1
julesjacobs:単純な数学的計算を解くためにhaskellとSchemeの両方を少し使用しました。私はそれらの言語がまったく得意ではないので、もっと複雑な問題を解決する方法があります。今では十分に速くすることができません。
martiert 2009年

95

私はこれについて自分で調査し、関数型言語を使用する理由のリストに並行性を追加するかもしれないと考えました。近い将来のある時点で、同じCPUテクノロジーを使用してプロセッサ速度を上げることができなくなることを確認してください。アーキテクチャの物理学はそれを許可しません。

そこで、並行処理が登場します。

残念ながら、ほとんどのOOP言語は、データ間の相互依存性のために、一度に複数のプロセッサを利用することはできません。

純粋な関数型プログラミング言語では、これらの関数は外部の状態情報を変更しないため、コンピューターは一度に2つ(またはそれ以上)の関数を実行できます。

これはあなたが楽しむことができる関数型プログラミングに関する優れた記事です。


38
ほとんどのオブジェクト指向言語は、任意の数のプロセッサを利用できないとは言えません。プログラムが効率的で信頼性の高い方法で同時に多くのプロセッサを利用するには、そのプログラムは、ほとんどの計算集約型のコード単位が純粋関数のように動作するように編成する必要があります。ほとんどの言語でそのようにプログラムを編成することが可能です。関数型言語では、命令型(オブジェクト指向を含む)言語よりも簡単に実行できます。
ザック

2
その記事をリンクしていただきありがとうございます。それは本当に私のために物事を説明するのに役立ちました。
guptron 2014

13

私の友人は、彼の大学教授の1人が次のようなことを言っていると引用しました。

上部にデータ型があり、左側にそれらのデータ型の操作があるグリッドを描画します。グリッドを垂直にスライスすると、OOを実行します。グリッドを水平方向にスライスすると、FPを実行します。

私の答えは、FPは、OOと同じくらい幅広いアプリケーションでプログラミングするための完全に実行可能なアプローチであるということです。他のプログラミング言語選択の議論と同様に、私はより重要な質問は次のとおりだと思います。

  1. 新しい表記法と新しい考え方を学ぶことに投資する時間はありますか?
  2. 検討している言語のうち、ホイールの再発明に行き詰まらないほど十分に豊富なライブラリがあるのはどれですか?

最初の質問に関して、これを主に学習価値のために行っているのであれば、Haskellを見ることをお勧めします、サポート資料(本、記事、活発なコミュニティなど)が豊富であるため、します。

2番目の質問に関しては、Haskellにはさまざまなライブラリがあります(ただし、一部は他よりも成熟しています)が、Scala(JVMで実行されるハイブリッドOO関数型言語)には、機能スタイルに徐々に移行できるという利点があります。 、そしてあなたはあなたが利用できるJavaアクセス可能なライブラリの全範囲を持っています。


私は大学でSchemeを学んだので、経験のためだけに関数型プログラミングを学びたくありません。実用的な理由から、関数型言語を学びたいと思います。
Alex Baranosky 2008

9

事実上、PPで実行できることはすべてFPでも実行でき、逆の場合も同じです。これは、何かをコーディングするための別の方法です。問題に対する別の視点と、それを解決するための別の方法です。

ただし、FPを使用する人はそれほど多くないため、問題は、優れたライブラリの欠如、移植性/保守性(メンテナは、SchemeよりもC ++で記述されたものを理解する可能性が高いため)、およびドキュメントとコミュニティの欠如にあります。いくつかのドキュメントがあることは知っていますが、それをC ++、C#、またはJavaと比較すると、私が何を意味するのか理解できます。

ただし、本当にFPを実行したい場合は、C ++およびC#でもこのスタイルを使用できます。もちろん、標準ライブラリを使用する場合、100%FPにはなりません。残念ながら、C#が関数型プログラミングで使用するように最適化されているとは思わないため、パフォーマンスの問題が多数発生する可能性があります。

これはもっと主観的な投稿であり、私がFPについて考えていることです。厳密な宣言ではありません。


8
「PPでできることは事実上すべてFPでできる」 -実際、それはまさにすべてです。
BlueRaja-Danny Pflughoeft 2010

2
@ BlueRaja-チューリング完全性について言及していますか?もしそうなら、あなたの言うことは続きません。たとえば、コンウェイのライフゲームはチューリング完全ですが、Cのようにビデオカードドライバーを作成するために使用することはできません。同様に、Haskellで作成された最新のゲームはありません。FPで実行できます!=理論的には理論上のFPで実行できます。
Luigi Plinge 2011年

@LuigiPlingeBlueRajaに同意する必要があります。Haskellで書かれたいくつかのLinuxドライバーについて議論しているHaskellers。 リンクはありませんが、OSがHaskellで書かれていると聞きました(他の関数型言語も可能です)。ゲームに関する限り、最新のゲームがC#またはJavaで記述されているのはわかりませんが、そのようなゲームには使用できないということですか? とにかく、FPで書かれているゲームの例。また、私のリンクのほとんどは、純粋に関数型言語であるHaskellであることを忘れないでください。
austinprete 2011年

@PardonMyRhetoric明らかに、Haskellでゲームを作成して計算を行うことはできますが、速度は数倍遅くなり、メモリ使用量は多くなります。したがって、BlueRajaのステートメントの反例は、FPで「Cにあるのと同じくらい高速で多くのメモリを使用するゲーム」を書くことができないということです。これは実際の問題であり、衒学的なトリックではありません(そして、私はFPをbashするつもりはまったくありません-私は今Scalaをコーディングしています!)。
Luigi Plinge 2011年

1
@PardonMyRhetoricこれも慣用的なFPである必要があります。HaskellのパフォーマンスがCのパフォーマンスに近いことを示すベンチマークは、ほとんどのHaskellプログラマーが記述できない「低レベル」のユニディオマティックスタイルで記述されています。たとえば、Haskellコードを出力してCコードをコンパイルするだけで、同様のパフォーマンスを実現できます。しかし無意味です。関連する実際的な問題は、「できること」と「できること/できること」の違いです。何かが難しすぎる場合、理論的に可能であるかどうか(そして誰にとって「可能」であるか)はそれほど重要ではありません。
Luigi Plinge 2011年

4

関数型言語は多くの状況で優れています。特定の関数型言語のライブラリに依存します。

「オブジェクト指向プログラミング言語をいつ使用するか」という質問にどのように答えますか?


1
「いつオブジェクト指向プログラミング言語を使うべきですか?」何かを計算でモデル化したいときは、一方で、fpが直感的な答えになるという問題を探していましたが、私はまだ探しています。それがこの投稿を見つけた方法です。
jimjim

@Arjang関数型プログラミングは、出力を生成するために入力のみを必要とする計算アプリケーションで非常に役立つと思います。可変性、ノー反復なし
EdgeDev

3

これはかなり主観的な質問ですが、関数型言語はドメイン固有言語の解析によく使用されることを付け加えたいと思います。機能的な性質は、文法の構文解析に適しています。


2
DSLを解析しますか?Lispマクロなどでは、DSLはLispプログラムで解析されるものではなくマクロとして実装されていると思いました。Lisp以外の言語のYMMV。:-P
クリスジェスター-ヤング

1

私が見たところ、それは機能性よりも味の問題です(しゃれは意図されていません)。特定のタスクで本質的に良くも悪くもする言語のスタイルについては、実際には何もありません。


2
@ JonHarrop-それについて詳しく説明しますか?私はそれがそれほど明白であるとは思いません、そしてあなたがあなたが単なるブーステリシムから人々を投票しているという印象を残したならばそれは残念です。
TED 2013年

1
MLファミリーの言語は、ツリー(式ツリーなど)を操作するためのパターンマッチングなどの高度な言語機能を追加して、メタプログラミング用に特別に作成されました。その結果、この言語族は本質的にその特定のタスクではるかに優れています。
JD 2013年

1
@ JonHarrop-私はそれを受け入れます。ただし、関数型言語全般ではなく、MLについて話していることになります。私はDSLを大いに信じているので、特定の言語をその設計された正確なタスクに使用することに異議を唱えることはありません。
TED

今日、パターンマッチングは、OCaml、F#、Scala、Haskell、Clojure、Erlangを含むほぼすべての関数型言語で見られます。たとえば、私は最近、数学に焦点を当てたクライアント向けの特注のビジネスルールエンジンを構築しました。これは1,000行のF#であり、主にインタプリタです。パターンマッチングのおかげで、字句解析、解析、型チェック、入力の解釈がすべてはるかに簡単になります。
JD

@JonHarrop ..しかしすべてではありません。それは関数型言語の固有の機能ではなく、それが質問の対象でした。
TED 2013年

1

一般に、問題の解決策を表現するのが最も簡単な言語を使用します。関数型プログラミングの場合、これは問題の解決策が関数の観点から簡単に表現される場合です。ため、この名前が付けられています。一般に、数学演算、AI、パターンマッチングに適しています。一般に、答えを得るために適用しなければならない一連のルールに分解できるものはすべて。問題を十分に分析して初めて、使用する「最適な」言語を実際に決定できます。これは、擬似コードが役立つところです。FPのような擬似コードを書いていることに気付いた場合は、FPを使用してください。

もちろん、すべての完全なプログラミング言語は機能的に同等であるため、解決できる問題に関して、どの言語を選択するかは実際には重要ではありません。主な効果は、コーディングの効率と精度、およびメンテナンスの容易さの観点からです。

また、巧妙に設計されたAPIを使用して、オブジェクト指向言語内でFPを模倣することが可能であることにも注意してください。たとえば、メソッドチェーンを使用してFP DSLをシミュレートする多数のJavaライブラリ(JMockはその一例です)を見てきました。次に、次のような構成が表示されます。

logger.expects(once()).method("error") .with( and(stringContains(action),stringContains(cause)) );

これは基本的に、モックオブジェクトの呼び出しシーケンスが正しいかどうかを判断するために評価される関数を構築します。(http://www.jmock.org/yoga.htmlから盗まれた例)

他のオブジェクト指向言語でのもう1つのFPに似た構文は、Rubyなどのクロージャの使用です。


2
「...どの問題を解決できるかという点では、どちらを選択してもかまいません」。あなたがあなたの問題を解決するために無限の時間とお金を持っている場合にのみ。
JD 2013年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.