なぜ関数型プログラミングに対する現在の熱意があるのですか?[閉まっている]


50

最近、Scala、Clojure、およびF#に関して、関数型プログラミング言語について多くの熱意を聞いています。私は最近、FPパラダイムを学ぶためにHaskellの勉強を始めました。

私はそれが大好きです、それは本当に楽しく、私の数学の背景に合います。

しかし、それは本当に重要でしょうか?明らかに、それは新しいアイデアではありません。

私の質問は次のとおりです。

  1. 最近のFP熱意に貢献したものは何ですか?オブジェクト指向に飽き飽きしているだけなのか、それともFPを以前よりも必要にするために何か変更されたのか
  2. これはFPの未来を示していますか?または、これはオブジェクト指向データベースのような流行ですか?

言い換えれば、誰が私がこれがどこから来てどこへ行くのかを理解するのを助けることができますか?



13
重複ではありません-これは新しいアイデアではないので、なぜ人々が突然大騒ぎしているのかを尋ねています(その質問は客観的な違いをもっと求めています)。
ピーターボートン

2
人々は最近FPをめぐって大騒ぎしていますか?私にとってニュースですが、これは常に、FPが命令型プログラミングの世界をどのように引き継ぐかについて、あるグループが大騒ぎしているケースだと思いました。
クリス

1
StackOverflowでこの質問に回答したことがあると思います。
ケンブルーム

1
うん-FPはすでに古かった1989年にコロンビアでSchemeを学部生として使っていたとき、私は思う。それは私が推測する光沢のある新しいものだ。
ティム

回答:


33

関心の「爆発」をもたらしたFPの主要な革新の1つはモナドです。

1992年1月、フィリップ・ワドラーは、関数型プログラミングの本質と呼ばれる論文を書き、IOを扱う方法としてモナドを関数型プログラミングに導入しました。

純粋で怠zyな関数型プログラミング言語の主な問題は、IOを扱う際の有用性でした。「怠lazと副作用は、実用的な観点からは互換性がないため、プログラミングの「厄介な分隊」のメンバーの1つです。副作用を使いたい場合は、厳密な言語を使用した方が良いでしょう。」参照

モナド以前のIOの問題は、実際に何かに役立つプログラムでは純度を維持できないことでした。IOとは、ユーザーまたは環境からの入力と出力の取得など、状態の変化を扱うものを意味します。純粋な関数型プログラミングでは、すべてが不変であり、怠inessと純粋さを可能にします(副作用がありません)。

モナドはIOの問題をどのように解決しますか?さて、あまりモナドについて議論することなく、彼らは基本的にモナドへの入力として「ワールド」(ランタイム環境)を取り、出力として新しい「ワールド」を生成し、結果:type IO a = World->(a、世界)。

そのため、最大の問題であるIO(およびその他)が解決されたため、FPはますます主流になりました。ご存じのとおり、既存のオブジェクト指向言語への統合も行われています。LINQは、たとえばスルーとスルーなどのモナドです。

詳細については、回答で参照されているモナドと論文について読むことをお勧めします。


非常に有益です、ありがとう。私はこの答えを受け入れていますが、それが正しいことと他の人が間違っているからではなく(私はいくつかを支持しました)、それは結果の可視性に値すると思うからです。
エリックウィルソン

しかし、より適切な例はtype IO a = UI -> (a, UI)素晴らしい答えでしょう。
ChaosPandion

@Richard:「type IO a = World->(a、World)」はあまりにも良すぎて本当ではありません(私はモナドを得ることはないと思っていました)。LINQをモナドにたとえたのは、ラムダをLINQ演算子に渡すと、ラムダがその環境全体を「見る」からだと思いますか?
ステファンモノフ

@Stefan:ラムダが環境を認識していると言うのはいくぶん正確に聞こえますが、私はそれについて100%明確ではありません。ただし、100%の確実性で、LINQはモナドであると言えます。これは、クリエイターが何度もそう言っているからです。SelectManyは、HaskellのBindとまったく同じです。"The Marvels of Monads"を読んでいない場合(blogs.msdn.com/b/wesdyer/archive/2008/01/11/…)強​​くお勧めします... LINQが実際にモナドであることが明らかになります。乾杯。
リチャードアンソニーハイン

1
@Job、上記のコメントで参照されているblogs.msdn.com/b/wesdyer/archive/2008/01/11/…を参照してください。
リチャードアンソニーハイン

30

主要な問題の一つは、アセンブラ等のCやJava、C#、などの伝統的な言語のプログラミング時あなたはぎこちない持っていることをされたシーケンスのステップを使用すると、特定のタスクを達成するために取る必要があり、あなたは最初にすべての依存関係を用意している必要があるためと以前の依存関係

例:Aを実行するには、BとCが存在している必要があり、BはDとEに依存しているため、次のような結果になります。

  • D
  • E
  • C
  • B
  • A

材料を使用する前に準備する必要があるためです。

関数型言語、特に怠zyな言語は、これを逆さまにします。AにBとCが必要であると言って、言語ランタイムにBとCを取得するタイミングを計算させる(これにより、DとEが必要になります)ため、Aを評価するために必要なときにすべて評価されます。ビルディングブロック。これにより、小規模で簡潔なプログラムが作成されます。遅延言語では、実際に使用される要素のみが計算されるため、使用する前にデータ構造全体をメモリに保存する必要がないため、無限リストを使用することもできます。

本当に素晴らしいトリックは、この自動「ああ、私にはBとCが必要」メカニズムがスケーラブルであることです。シーケンシャルプログラムのように、この評価がどこで、いつ行われるかについての制限がないためです。同時に、異なるプロセッサーやコンピューターでも。

それが関数型言語が興味深い理由です-プログラマーが手動で行うのではなく、「いつ何をすべきか」メカニズムがランタイムシステムに引き継がれるからです。これは、JavaからCへの自動ガベージコレクションと同じくらい重要な違いであり、CよりもJavaで堅牢でスケーラブルなマルチスレッドソフトウェアを作成する方が簡単な主な理由の1つです。関数型言語のスケーラブルなマルチスレッドソフトウェア...


3
もちろん、これは1950年に当てはまりました。
エリックウィルソン

1
@FarmBoy、そうではありませんが、今日です。

5
これは依存性注入とどのように違いますか?
ビルK

2
@ビルK、優れた観察-私は自分でその接続をしていませんでした。違いは、注入されるオブジェクト(少なくともJavaでは)が熱心に評価され、遅延評価ではないことです。無限リストを挿入することはできません。

1
@ThorbjørnRavn Andersen無限リストが役立つ理由を理解できませんが、実際には(無限リスト)タイプの演算の合計を実行できますか?ありそうもない。それ以外の場合は、Javaがイテレータを使用する方法のように聞こえます。オブジェクトを要求したときにのみオブジェクトをインスタンス化するようにイテレータをコーディングするだけです。 )
ビルK

21

80年代後半/ 90年代前半に、コンピューターはSmalltalkスタイルのOOPに十分なほど強力になりました。現在、コンピューターはFPに十分に強力です。FPはより高いレベルでプログラミングを行っているため、プログラミングはより快適ですが、特定の問題を解決する最も効率的な方法ではありません。しかし、コンピューターは非常に高速なので気にしないでください。

純粋に機能的なプログラミング言語を使用すると、状態が変化するコードを隔離する必要があるため、マルチコアプログラミングが簡単になります。

また、プログラミング言語の境界線は今日ぼやけています。別のパラダイムを使用する場合、1つのパラダイムを放棄する必要はありません。ほとんどの一般的な言語でFPを実行できるため、エントリの障壁が低くなります。


6
答えを追加しようとしていましたが、あなたはあなたの最後の文で私の主張を打ちました。関数型プログラミングは、1台のマシンのコアの数が増えるにつれてますます一般的になります。固有の状態の欠如により、機能プログラムをプロセッサー間で機械的に分割することが容易になります(つまり、純粋に機能的なプログラムがある場合、コンパイラーは理論的には最小限の労力で並列処理を処理できますyoutube.com/watch?データの並列性については、v = NWSZ4c9yqW8参照してください)。
イナイマティ

1
@Inaimathi Ditto。関数型プログラミングは非常にスケーラブルであるため、マルチコアアーキテクチャ上で理にかなっています。
EricBoersma

最初のコメントは、回答が編集されてから追加のステートメントが含まれる前に書かれていることに注意してください。
イナイマティ

そのために残念。この点を忘れました。
レニープログラマー

機能的コンパイラはOOPSと同じように最適化されたマシンコードを生成できないことは本当に一般的に受け入れられていますか?私はそれが真実でなければならない理論的な理由を考えることはできません。また、OOPSよりも高度な最適化が可能な方法を考えることができます。
ジェレミー

7

今日の分散コンピューティングの必要性。

FPは、状態を持たないビルディングブロックとして関数を使用するため 、同じパラメーターでn回呼び出すと、常に同じ値が返され、副作用はありません。

したがって、同じ機能を多数のマシンに送信して、並行して作業を実行することができます。

オブジェクト指向のパラダイムでは、ビルディングブロックはオブジェクトであり、定義上ほとんどステートフルであるため、これは少し難しくなります。同じメソッドを複数回呼び出す場合、データの破損を防ぐために、内部データの同期に注意する必要があります。FPパラダイムはまだ可能ですが、計算を分散する必要があるいくつかのシナリオではOOよりもうまく機能します。

FP(およびある程度のNoSQL)の出現は、数十万台のコンピューターが並行して動作するという驚くべきコンピューティングの結果と、それがいかに簡単かという話に続きます。

しかし、これはおそらく、この種のセットアップを必要とする種類のアプリケーションのニッチにすぎません。多くの場合、他の多くのアプリケーション/システム、手続き型およびオブジェクト指向は問題なく動作します。

プログラミングの視野を広げ、かつて学問を超えないだろうと考えていたこれらの概念を再び取り入れようとしています。

私は何年も前にLispでプログラムすることを学びました。今ではほとんどすべてのことを忘れていますが、再帰のような概念を非常に簡単に理解するのに役立ちます。


2
質問は、FPに似た言語の利点について尋ねています。あなたが説明したことは、従来の言語を使用して行うこともできます。
Pacerier 14

6

私たちは、マルチコア処理が科学研究室のバックルームや特殊なハードウェアで行われるだけのものではない時代に移行しています。現在、コモディティプロセッサで行われています。関数型プログラミングは、少なくとも私がこれまでさらされてきたバリアントのほとんどは、一般に、副作用のない、ステートレスな計算ユニットに視点を広げようとします。これは、プロセッサ間で状態を維持する必要がないため、マルチコア作業の典型的なパラダイムです。

これは理由の1つにすぎませんが、関数型プログラミングが定着するのを見るのに十分な理由です。


5

その質問に対する主な答えは「暴露」だと思います。

関数型プログラミングは新しいものではありません。私は12年ほど前に大学でHaskellを教えられ、それが大好きでした。しかし、私の仕事で言語を使うことはめったにありませんでした。

最近、マルチパラダイムアプローチを使用するメインストリームで注目を集めている多くの言語があります。F#、JavaScriptが代表的な例です。

特にJavaScriptは、jQueryPrototypeのような機能スタイルのフレームワーク言語で使用される場合、動的な近代的なWebサイトでのすべての作業により、多くの人々にとって日常言語になりつつあります。この機能的なスタイルへの露出は、特に命令型のスタイルに自由に戻ることができる場合に、それが与える力を人々に認識させます。

ひとたび公開されると、より本格的な機能言語のバリアントを試して、日常のタスクに使用し始めます。

F#がVisual Studio 2010でファーストクラスの言語になり、jQuery(など)が非常に重要になっているため、これらの言語を使用することは、孤立したプログラムで遊んだり作成したりするだけではなく、現実的になりつつあります。

コードは保守可能でなければならないことを忘れないでください-企業がそれらを安全に使用できるようにするには、開発者の非常に多くが言語を使用およびサポートする必要があります。


3

、この話アンダース・ヘルスバーグは、トピックに関する彼の見解を説明しています。

[編集]

申し訳ありませんが、リンクが間違っていました。今、それは正しい場所を指しています。

1時間のトークのいくつかのポイントの非常に短い要約:

関数型言語は手続き型言語よりも宣言型のプログラミングスタイルを可能にするため、通常、FLで記述されたプログラムは、howではなくwhatに集中します。FLは洗練された数学的構造のため、コンパイラによる最適化と変換も容易であり、メタプログラミングと組み込みDSLの構築も容易です。これらすべてが一緒になって、関数型プログラムは手続き型プログラムよりも簡潔で自己文書化されます。

また、近い将来のメニーコア時代に直面して、プログラミング言語はマルチスレッド/処理をさまざまな方法で利用できる必要があります。シングルコアマシンでのマルチスレッドは、実際にはタイムシェアリングメカニズムであり、システムのアーキテクチャはこれを反映しています。メニーコアマシンでのマルチスレッドは非常に異なります。Funcional言語は、状態をほとんど回避するため、並列化に特に適しています。そのため、共有可変データの整合性について心配する必要はありません(共有可変データがない傾向があるため)。


1
まとめていただけますか?

1
@Thorbjornそれは要約できなかった男を思い出させる。(それを指示しないで、著者に答えてください。)
マークC

1
リンクは適切な場所にもリンクしていません。
ケンブルーム

2

それは、関数型プログラミングのパラダイムとウェブ向けのプログラミングとの密接な相関関係に関係していると思います。

Ruby on Railsは、機能的(へん)Webアプリケーションへの非常に迅速なパスを提供するため、機能的プログラミングのアプローチ全体を大幅に緩和しました。これについてSOで興味深い議論があり、1つの特定の答えが際立っています。

関数型プログラミングはWebアプリに非常によくマッチします。WebアプリはHTTPリクエストを受信し、HTMLの結果を生成します。これは、リクエストからページへの機能と考えることができます。

通常、長時間実行されるプロセス、ステートフルUI、および複数の方向のデータフローがあるデスクトップアプリと比較してください。これは、状態とメッセージの受け渡しがあるオブジェクトを懸念するオブジェクト指向に適しています。

関数型プログラミングは古くから存在しているので、グリーンフィールドWebプロジェクトのLisp開発者を探している求人広告があまり見られないのはなぜだろうか。


基本的なプロトコルはステートレスであるため、機能的な類推は偶発的にウェブにのみ適用されると思います。Webアプリケーションは、実際にはステートレスではありません。これは、実際には、何らかの形で常にHTTPを回避する必要がある理由です。
ムラデンJablanović

@Mladen Hmmm、クライアントとサーバー間の通信状態(HTTP)とアプリケーション状態(DAOなど)を混同している可能性はありますか?ここからStefan Tilkovを引用(codemonkeyism.com/stateless-applications-illusion)「Webアプリケーションでは、個々のリクエストには、前のリクエストが発生したかどうかに関係なく処理可能な十分な情報が含まれている必要があります。状態は問題ありませんが、クライアント側の状態は問題ありません。一時的な通信(セッション)状態は、スケーラビリティとブックマーク機能を台無しにするためではありません。」これがRESTの基礎です。
ゲイリーロウ

1
paulgraham.com/avg.htmlを読んで、Lisp開発者を探している求人広告がそれほど多くない理由をよりよく理解してください。

@ThorbjørnRavn Andersen良い記事。私のLispエディターを打ち破るように促します。
ゲイリーロウ

1

関数型プログラミングは、何年も前にオブジェクトに手を出したときと同じ「うわー、これは新しい」というチクチク感を与えてくれます。

FPはまったく新しい概念ではありませんが、90年代に「全員」が手続き型プログラミングから突然船を飛び出したとき、それが本当のブレイクになったときもOOではありませんでした。これは主に、Javaとその後のC#のタイムリーな成功によるものです。

言語の次のバッチが同じ方法で広がり始めると、最終的にFPでも同じことが起こると思います。少なくとも一部のサークルでは、ScalaやF#などの言語で既に持っているのと同じです。


OOはFPよりもはるかに若いですが、はるか前に脚光を浴びました。括弧があまりにも多くの人を怖がらせたと思います
ハビエル

1

私の質問は次のとおりです。1.最近のFPの熱狂に貢献したものは何ですか?オブジェクト指向に飽き飽きしているだけなのか、それともFPを以前よりも必要にするために何か変更されたのか 2.これはFPの将来を示していますか?または、これはオブジェクト指向データベースのような流行ですか?

他の人は、技術的な理由があります。

FPが平均的な開発者とマネージャーのタイプの間で牽引力を得ている主な理由は、マルチコアCPUのより良い使用を可能にすることを約束していると思います。私が読んだすべてのものから、FPはより簡単な(簡単ではない)並列プログラミングを可能にします。

将来の広範な使用は、約束が現実であり、実現されている場合です。


それは大きな「if」です。「英語」であるCOBOLは、誰でもプログラムできることを意味していました。AIはプログラミングを時代遅れにするでしょう。オブジェクト指向は、ティンカートイを組み立てるのと同じくらい簡単にプログラミングをするつもりでした。コーダーは、常に「次の大きい事」を探して、岩のグルーピーのようなもので、その後1、および1 ...
マイクDunlavey

0

私はそれが2つの傾向の組み合わせだと思う:

  1. 主流の言語に追加される機能的な機能(C#など)。
  2. 新しい関数型言語が作成されています。

最初の傾向にはおそらく自然な制限がありますが、私の推測では、新しい言語は、少なくともオプションとして、関数型プログラミングをサポートする必要があります。


0

以前は、オペレーティングシステムのネイティブAPIを使用してデスクトップで実行するプログラムを作成していましたが、これらのAPIは(一般的に)Cで作成されていたため、ネイティブAPIのプログラムを作成する場合は、ほとんどの場合、そのプログラムをCで書きました。

過去10年程度の新しいイノベーションは、特にプラットフォームAPIが関係のないWeb開発など、さまざまなAPIが普及するためだと思います(Webページの構築は基本的に文字列操作を伴うため)。Win32 APIまたはPOSIX APIを直接コーディングしていないため、人々は関数型言語を自由に試すことができます。


0

それは素敵で気の利いた、あなたの脳をくすぐります。それはいいです。

また、私見、古典的な時流です。問題を探しているソリューション。

エンジニアによって設立されたスタートアップ企業はすべて、お気に入りのアイデアに目を奪われ、しばらく燃え続けますが、必要なものを提供することで設立された企業は静かに追いついています。

それは、私が見たい新しいアイデアであり、気の利いたアイデアベースのプログラミングではなく、ニーズベースのプログラミングです。たぶんそれは平凡に聞こえるかもしれませんが、実際にはかなり創造的で気品があります。


-1

間違いなくF#のためです。ただし、どちらが原因で、どちらが結果であるかを判断するのが難しい場合があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.