web-dev-qa-db-ja.com

関数型プログラミングの増加?

最近、関数型プログラミング言語 人気が高まっている に気づきました。 Tiobe Index が昨年と比較して人気がどのように上昇しているかを最近見ましたが、このインデックスによると、ほとんどの言語は上位50の人気言語にさえ到達していません。

そして、これはかなり長い間当てはまります。関数型プログラミングは、他のモデル(つまり、オブジェクト指向プログラミング)ほど普及していません。

関数型プログラミングの力への関心が生まれましたが、マルチコアの人気が高まっている今、開発者はすでにHaskellやErlangなどの言語で過去に検討されている並行処理の他のモデルに関心を示し始めています。

大きなコミュニティの受け入れがないにもかかわらず、この種の言語がますます出現し続けているという事実に大きな関心を抱いています。 Clojure(2007)、Scala(2003)、F#(2002)は、最近の過去10年の3つの例にすぎません。

私自身、HaskellとScalaを学ぶために時間を費やしてきました。そして、私はパラダイムに大きな可能性を見出しました。それは、長い間そこにいても、私にとっては新しいものでした。

そしてもちろん、私の最大の質問は、これらのいずれかがそれらに何らかの努力をすることを検討するほど十分に人気が高くなるかどうかですが、これは人々がすべてについて大騒ぎしているにもかかわらず、Mandrakeでさえ答えられない質問です。

私が聞きたいのは:

  • 特定のタスクを実行するためにより適切な関数型プログラミング言語を検討する必要があるのはどのシナリオですか?最近、非常に人気のある並列プログラミングのマルチコア問題に加えて。
  • 関数型プログラミング言語に切り替えることにした場合、私が直面する最大の落とし穴はどれですか。 (パラダイムの変更と遅延評価のためにパフォーマンスを評価するのが難しいことに加えて)。
  • 非常に多くの関数型プログラミング言語があるので、ニーズに合ったものをどのように選択しますか?

さらなる研究のための提案は歓迎以上です。

私はウェブで意見を検索しましたが、この新しい人気のすべては、今 ムーアの法則 の壁にぶつかろうとしているという考えから来ているようです。関数型プログラミング言語が登場し、英雄的に救われます。しかし、これが事実である場合、パラダイムに適応する既存の一般的な言語の可能性がより高いと私は言うでしょう。

おそらくこれらの言語での作業経験が豊富な方は、このテーマについてより深い洞察を得ることができます。すべてのあなたの意見はより高く評価され、慎重に検討されます。

前もって感謝します!

42
edalorzo

特定のタスクを実行するのにより適した関数型プログラミング言語を検討する必要があるのはどのシナリオですか?最近、非常に人気のある並列プログラミングのマルチコア問題に加えて。

いくつかの変換ステップを使用して派生データ要素のシーケンスを作成することを含むすべて。

基本的に、「スプレッドシートの問題」です。初期データと、そのデータに適用する行ごとの計算のセットがあります。

私たちの生産アプリケーションは、データのいくつかの統計的要約を行います。これはすべて機能的に最適な方法です。

私たちがよく行うことの1つは、3つの巨大なデータセット間のマッチマージです。 SQL結合に似ていますが、一般化されていません。これに続いて、派生データのいくつかの計算が行われます。これはすべて、単なる機能変換です。

アプリケーションはPythonで記述されていますが、ジェネレーター関数と不変の名前付きタプルを使用した関数形式で記述されています。これは、下位レベルの関数の組み合わせです。

次に、機能的な構成の具体例を示します。

for line in ( l.split(":") for l in ( l.strip() for l in someFile ) ):
    print line[0], line[3]

これは、関数型プログラミングがPythonなどの言語に影響を与える1つの方法です。

時々この種のものは次のように書かれます:

cleaned = ( l.strip() for l in someFile )
split = ( l.split(":") for l in cleaned )
for line in split:
     print line[0], line[3]

関数型プログラミング言語に切り替えることにした場合、私が直面する最大の落とし穴はどれですか。 (パラダイムの変更と遅延評価のためにパフォーマンスを評価するのが難しいことに加えて)。

不変オブジェクトは最も難しいハードルです。

多くの場合、既存のオブジェクトを更新する代わりに、新しいオブジェクトを作成する値を計算することになります。それがオブジェクトの変更可能な属性であるという考えは、破るのが難しい精神的な習慣です。

派生プロパティまたはメソッド関数は、より良いアプローチです。ステートフルオブジェクトは、破壊するのが難しい習慣です。

非常に多くの関数型プログラミング言語があるので、ニーズに合ったものをどのように選択しますか?

最初は関係ありません。学習する言語を選択してください。何かを知ったら、ニーズに合わせて別のものを選ぶことを検討する立場にいます。

私はHaskellについて読み、Python不足しているものを理解しました。

24
S.Lott

「機能的」とはさまざまな機能の集まりであり、それぞれが独立して便利です。それぞれを個別に見るとより便利です。

不変性

慣れてきましたので、不変の結果を返すことができるときはいつでも、オブジェクト指向プログラムであっても、常にそうするようにしています。値型のデータがあると、プログラムについての理由がわかりやすくなります。通常、GUIやパフォーマンスのボトルネックなどの可変性が必要です。私のエンティティ(NHibernateを使用)も変更可能です(データベースに格納されているデータをモデリングしているため、これは理にかなっています)。

ファーストクラスタイプとしての機能

デリゲート、アクション、または関数を渡すことで、「真ん中のパターンの穴」のように、実際の問題のクラス全体を解決するのに非常に便利な方法です。また、デリゲート、アクション、または関数をオブジェクトに渡す方が、そのクラスでイベントを宣言してそのイベントをフックするよりもクリーンであることもわかりました(通常、「リスナー」は1つだけであると想定)。リスナーが1つあることがわかっている場合は、コールバックアクションをコンストラクターパラメーターとして渡すことができます(そして不変のメンバーに保存できます!)

関数を作成できる(たとえば、Action<T>Actionだけに変換することも、いくつかのシナリオで非常に役立ちます。

Lambda構文は、関数をファーストクラスタイプに昇格させた場合にのみ取得されるため、ここでも注意する必要があります。ラムダ構文は非常に表現力豊かで簡潔にすることができます。

モナド

確かに、これは私の弱点ですが、私の理解では、asyncワークフローなどのF#の計算ワークフローはモナドであると理解しています。これは微妙ですが非常に強力な構成です。 C#でyieldクラスを作成するために使用されるIEnumerableキーワードと同じくらい強力です。本質的には、内部でステートマシンを構築していますが、ロジックは線形に見えます。

遅延評価と再帰

これらは常に関数型プログラミングの機能としてひとまとめにされていますが、そうでなければ命令型言語に急速に移行し、もはや関数型と呼ぶのが難しいため、これらをまとめました。

S式

これをどこに置くかはわかりませんが、LISPのS式やLINQ式など、コンパイルされていないコードをオブジェクトとして扱う(そしてそれを検査/変更する)機能は、いくつかの点で、関数型プログラミングの最も強力なツール。ほとんどの新しい.NET「流れるような」インターフェイスとDSLは、ラムダ構文とLINQ式の組み合わせを使用して、非常に簡潔なAPIをいくつか作成します。 Linq2Sql/Linq2Nhibernateは言うまでもなく、C#コードはC#コードではなくSQLとして「魔法のように」実行されます。

それはあなたの質問の最初の部分に対する長い答えでした...今...

関数型プログラミング言語に切り替えることにした場合、私が直面する最大の落とし穴はどれですか。 (パラダイムの変更と遅延評価のためにパフォーマンスを評価するのが難しいことに加えて)。

私が直面した最大の落とし穴は、関数型ソリューションと命令型ソリューションの使用の境界を見つけようとしていたことです。ただし、両方のアプローチを数回試した後、どちらがよりうまく機能するかを感じ始めます。

非常に多くの関数型プログラミング言語があるので、ニーズに合ったものをどのように選択しますか?

.NETに精通している場合は、F#を強くお勧めします。一方、JVMに慣れている場合は、常に Clojure があります。実用的というより学術的であるなら、私はCommon LISPまたはSchemeを使います。 Pythonを既にご存じの方は、すでに利用可能な関数型コンストラクトがたくさんあると思います。

23
Scott Whitlock

そして、これはかなり長い間当てはまります。関数型プログラミングは、他のモデル(つまり、オブジェクト指向プログラミング)ほど普及していません。

これは、プロのプログラマー(または少なくとも自分自身をそのように見ている人々)が開発したプログラムを数える場合に当てはまります。あなた自身をそのように考えていない人々によって開発されたプログラムを含めるためにあなたのネットをより広く広げるなら、FP(または少なくとも関数型のプログラミング)はOOにかなり近い(Excel、Mathematica 、Matlab、R ...「最新」のJavaScript)。

特定のタスクを実行するのにより適した関数型プログラミング言語を検討する必要があるのはどのシナリオですか?最近、非常に人気のある並列プログラミングのマルチコア問題に加えて。

私の個人的な意見では、マルチコアはFPのキラー機能ではありません(少なくともHaskell、Scala、Clojure、F#コンパイラがキャッシュの局所性の問題を解決するまで)。キラー機能は、mapfilterfoldなどの大規模なアルゴリズムグループをより簡潔に表現できる機能です。これは、最も一般的なFPよりも簡潔な構文を持つOO言語によって複雑化されています。

さらにFPをリレーショナルモデルに近づけることで、RDBMSとのインピーダンスの不一致が減少します...これもまた、少なくともプログラマー以外にとっては非常に素晴らしいことです。

また、「正確さ」の要件を満たすのが特に難しい場合-テストするのが難しい形式(科学計算/大規模データ分析では、以前は未知であり、特定できない結果が得られることが目標である場合が多い)FPには利点があります。

関数型プログラミング言語に切り替えることにした場合、私が直面する最大の落とし穴はどれですか。

  • ツールのサポートの欠如(F#と一部のLispは例外であり、Scalaは進行中です)
  • ハードウェアからパフォーマンスの最後のビットを絞り出すのが難しい
  • コミュニティは、多くの場合、商用ソフトウェア開発プロジェクトの大規模なグループが直面する問題とは異なる問題に焦点を当てています
  • 非常に少数の開発者使用の経験FP産業環境での経験そして、もしそれらを見つけることができるなら、おそらく金融業界が提供できる給与と利益と競争しなければなりません
  • 関数型のプログラミングはデバッグが難しくなる傾向があります。つまり、構成された関数の長いチェーンの結果の間を観察することは、ほとんどの(すべての)デバッガーでは通常不可能です。

非常に多くの関数型プログラミング言語があるので、ニーズに合ったものをどのように選択しますか?

  • どのプラットフォーム(JVMや.Netなど)ですでにライブラリ/フレームワークを終了することで問題を解決できますか?これらの問題を直接表現できる言語構造はありますか?

  • アプリケーションの空間と時間のパフォーマンスに対して、どれだけの低レベルの制御が必要ですか?

  • 「正確さ」の要件はどの程度厳格ですか?

  • 開発者を再訓練したり、ソフトウェア開発で非常に収益性の高いニッチが提供するメリットと競争したりできますか?

15

関数型プログラミング言語に切り替えることにした場合、私が直面する最大の落とし穴はどれですか。 (パラダイムの変更と遅延評価のためにパフォーマンスを評価するのが難しいことに加えて)。

あなたが業界のC++/C#/ Java開発者であると仮定します...

何も学びたくない気難しい仲間のために準備してください。 「かつてはコーダーだったので」、悪い言語の選択を強いる先のとがった髪のボスに備える。モノイドについてあなたをひいきにしているフォーラムで、落ち着いた学者のために準備してください。 Scalaには末尾呼び出しの排除さえなく、Clojureはすべてのブラケットにフットペダルを本当に必要とし、Erlangを使い始めないので、無限の言語戦争に備えてください。

あなたがWebプログラマーなら、最大の落とし穴はおそらくあなたの髪になるでしょう。

非常に多くの関数型プログラミング言語があるので、ニーズに合ったものをどのように選択しますか?

私はプラットフォームから始めます:

  • OCamlはLinuxでは素晴らしいですが、Windowsではひどいです。
  • F#はWindowsでは素晴らしいですが、Linuxではひどいです。
  • ScalaとClojureはJVMで優れています。
9
Jon Harrop

この質問に対する1つの(確かに偏った)見方については、Bob Harperのブログ Existential Type をチェックしてみてください。カーネギーメロンは最近、関数型プログラミングを最初に教えるようにCSカリキュラムを再作成しました。他のパラダイムは関数型プログラミングの確固たる基礎が確立された後にのみ教えられ、新しいカリキュラムが実際に展開されるにつれてハーパーは一撃を与えます。

ハーパーは標準MLプログラミング言語の主要な開発者の1人であるため、この件についての彼自身の意見は事前に推測できると言っても過言ではありません。彼はこの立場について論争する議論については恥ずかしがりませんが、彼のケースも。

3
jimwise

特定のタスクを実行するのにより適した関数型プログラミング言語を検討する必要があるのはどのシナリオですか?最近、非常に人気のある並列プログラミングのマルチコア問題に加えて。

関数型プログラミングをいつ使用するかを示す魔法の公式はありません。これは、オブジェクト指向プログラミングが現在のプログラミング状況に適しているようなものではありません。これは、抽象化の別のセットとしてプログラムを構造化するもう1つの方法です。

関数型プログラミング言語に切り替えることにした場合、私が直面する最大の落とし穴はどれですか。 (パラダイムの変更と遅延評価のためにパフォーマンスを評価するのが難しいことに加えて)。

関数型プログラミングは遅延とは関係ありません。 MLとOCamlは関数型で厳密な言語です。直面する最大のハードルは、不変の値で物事を構造化し、副作用のために型システムで使用される抽象化に頭を包むことです。関数型言語は、型システムで副作用を非常に明示的にするため、最適化により適しています。 Haskellはモナドを使用しますが、純粋な関数型言語でエフェクトを使用する方法は他にもあります。 Cleanには一意性タイプがあり、開発中の他のいくつかの言語には他のものがあります。

非常に多くの関数型プログラミング言語があるので、ニーズに合ったものをどのように選択しますか?

私が知っているプログラミング言語の中で、関数型言語と呼ばれるのはHaskellとCleanだけだと思います。他のすべてのものは、型システムでそれらの影響を明示的にすることなく、副作用を許可します。したがって、関数型プログラミングの学習に時間を費やすつもりなら、おそらくHaskellがその法案に合う唯一のものです。私が知っている他のすべてのもの、Erlang、Scala、Clojureなどは、命令型言語の上に機能的な抽象化を提供するだけです。ですから、機能的パラダイムに少しずつ近づきたいのであれば、Scala=またはErlangをお勧めします。一度にすべてに取り組み、フラストレーションを諦めたいのであれば、Haskellを使うべきです。

2
davidk01

関数型言語でのインテルの現在の台頭は、並列計算に理想的であるという事実に起因すると思います。たとえば、map-reduceの全体的なアイデアは、機能パラダイムに基づいています。また、現在のスケールアウトの方がスケールアップよりもはるかに簡単で安価であることは明らかであるため、並列計算が増えることは間違いありません。民生市場でも、CPUはより多くのコアを取得しますが、GHzは増加しません。

編集:それはすべてに明らかではないので。

純粋な関数型プログラミングでは、関数は入力を受け取り、出力を生成し、副作用はありません。副作用がないということは、状態が共有されていないこと、つまり同期メカニズムが不要であることを意味します。同期は、並行/並列ソフトウェアの最も難しい部分です。したがって、それを純粋に機能的に行うと、基本的に、最も難しい部分を処理する必要がまったくなくなります。

Map-reduceについては、名前も関数型プログラミングに由来しています(マッピングとリデュースの両方が関数型パラダイムの典型的な操作です)。 map-reduceの両方のステップは関数であり、並行して実行され、入力を受け取り、出力を生成し、副作用はありません。つまり、これはまさに純粋な関数型プログラミングのアイデアです。

並列処理に使用されるFPのいくつかの例:

  • CouchDB-Erlangで構築
  • Facebookチャット-Erlangで構築
  • Twitter-Scalaで構築された大部分
1
vartec