関数型プログラミング

ウィキペディアから、無料の百科事典
ナビゲーションにジャンプ 検索にジャンプ

コンピュータサイエンスでは関数型プログラミングは、関数を適用して構成することによってプログラムを構築するプログラミングパラダイムです。これは宣言型プログラミングパラダイムであり、関数定義は、プログラムの実行状態を更新する一連の命令ステートメントではなく、を他の値にマップする式のツリーです

関数型プログラミングでは、関数は第一級市民として扱われます。つまり、他のデータ型と同じように、名前(ローカル識別子を含む)にバインドし、引数として渡し、他の関数から返すことができます。これにより、プログラムを宣言型構成可能なスタイルで作成できます。この場合、小さな関数がモジュール方式で組み合わされます。

関数型プログラミングは、純粋関数型プログラミング、すべての関数を決定論的数学関数、または純粋関数として扱う関数型プログラミングのサブセットと同義として扱われることがあります純粋関数が特定の引数を指定して呼び出されると、常に同じ結果が返され、可変状態やその他の副作用の影響を受けることはありませんこれは、命令型プログラミングで一般的な不純な手順とは対照的です。、副作用(プログラムの状態の変更やユーザーからの入力の取得など)が発生する可能性があります。純粋関数型プログラミングの支持者は、副作用を制限することにより、プログラムのバグが少なくなり、デバッグテストが容易になり、フォーマル検証により適していると主張しています[1] [2]

関数型プログラミングは、関数のみに基づく正式な計算システムであるラムダ計算から発展した、アカデミアにルーツがあります。関数型プログラミングは歴史的に命令型プログラミングほど人気が​​ありませんでしたが、 Common LispScheme[3] [4] [5] [6] ClojureWolfram Language[7]など、多くの関数型言語が今日、産業や教育で使用されています。 [8]ラケット[9] Erlang[10] [11] [12] Elixir[13] OCaml[14] [15] Haskell [16] [17]およびF#[18] [19]関数型プログラミングは、WebのJavaScript [20] 統計のR [21] [22] 財務分析のJ K Qなど、特定のドメインで成功を収めている一部の言語にとっても重要ですおよびXQuery / XSLT forXML_ [23] [24] SQLLex / Yaccなどのドメイン固有の宣言型言語可変値を許可しないなど、関数型プログラミングのいくつかの要素を使用します[25]さらに、他の多くのプログラミング言語は、関数型スタイルでのプログラミングをサポートしているか、 C ++ 11C#[26] Kotlin[27] Perl[28] PHP[29 ]などの関数型プログラミングの機能を実装しています。] Python[30] Go[31] Rust[32] Raku[33] Scala[34]およびJava(Java 8以降)[35]

歴史

1930年代にアロンゾチャーチによって開発されたラムダ計算は、関数適用から構築され正式な計算システムです1937年、アランチューリングは、ラムダ計算とチューリングマシンが同等の計算モデルであることを証明し[36]、ラムダ計算がチューリング完全であることを示しました。ラムダ計算は、すべての関数型プログラミング言語の基礎を形成します。同等の理論的定式化であるコンビネータ論理は、1920年代と1930年代にMosesSchönfinkelHaskellCurryによって開発されました。[37]

チャーチは後に、より弱いシステムである単純型付きラムダ計算を開発しました。これは、すべての用語にを割り当てることによってラムダ計算を拡張しました。[38]これは、静的に型付けされた関数型プログラミングの基礎を形成します。

最初の高レベル関数型プログラミング言語であるLISPは、1950年代後半に、マサチューセッツ工科大学(MIT)で、ジョン・マッカーシーによってIBM700 / 7000シリーズの科学コンピューター用に開発されました。[39] LISP関数は、Churchのラムダ表記を使用して定義され、再帰関数を許可するためにlabel構文で拡張されました。[40] Lispは最初に関数型プログラミングの多くのパラダイム機能を導入しましたが、初期のLispはマルチパラダイム言語であり、新しいパラダイムが進化するにつれて多数のプログラミングスタイルのサポートが組み込まれました。スキームなどの後の方言Clojure 、およびDylanJuliaなどの派生物は、きれいに機能するコアの周りでLispを単純化および合理化しようとしましたが、Common Lispは、置き換えられた多数の古い方言のパラダイム機能を保持および更新するように設計されました。[41]

1956年の情報処理言語(IPL)は、最初のコンピューターベースの関数型プログラミング言語として引用されることがあります。[42]これはシンボルのリストを操作するためのアセンブリスタイルの言語です。関数を引数として受け入れる関数に相当するジェネレーターの概念があり、アセンブリレベルの言語であるため、コードはデータである可能性があり、IPLは高階関数を持っていると見なすことができます。ただし、変更リストの構造と同様の必須機能に大きく依存しています。

Kenneth E. Iversonは、1962年の著書A Programming LanguageISBN 9780471430148 )で説明されているように、1960年代初頭にAPLを開発しましたAPLは、ジョン・バッカスFPに主な影響を及ぼしました。1990年代初頭、IversonとRogerHuiはJを作成しました。1990年代半ば、以前にIversonと協力していたArthur WhitneyがKを作成しました。これは、その子孫であるQとともに金融業界で商業的に使用されています。  

John Backusは、1977年のチューリング賞の講演「プログラミングをフォンノイマンスタイルから解放できるか?関数型スタイルとそのプログラムの代数」でFPを発表しました。[43]彼は、関数型プログラムを、「プログラムの代数」を可能にする「フォームの組み合わせ」によって階層的に構築されるものとして定義しています。現代語では、これは関数型プログラムが構成性の原則に従うことを意味します。[要出典] Backusの論文は、関数型プログラミングの研究を普及させましたが、関数型プログラミングに現在関連付けられているラムダ計算スタイルではなく、 関数レベルプログラミングを強調していました。

1973年の言語MLは、エジンバラ大学のRobin Milnerによって作成されDavid Turnerは、セントアンドリュース大学で言語SASLを開発しましたまた、1970年代のエジンバラでは、BurstallとDarlingtonが関数型言語NPLを開発しました。[44] NPLはクリーネの再帰方程式に基づいており、プログラム変換に関する研究で最初に導入されました。[45] Burstall、MacQueen、およびSannellaは、MLからのポリモーフィック型チェックを組み込んで、言語Hopeを生成しました。[46]MLは最終的にいくつかの方言に発展し、その中で最も一般的なものは現在OCamlStandardMLです。

1970年代に、ガイL.スティールジェラルドジェイサスマンは、ラムダペーパーと1985年の教科書「計算機プログラムの構造と解釈」に記載されているように、スキームを開発しましたスキームは、字句スコープを使用し、関数型プログラミングを促進する機能である 末尾呼び出しの最適化を必要とするlispの最初の方言でした。

1980年代に、PerMartin-Löf直観主義型理論(構成的型理論とも呼ばれます)を開発しました。これは、関数型プログラムを依存型として表現される構成的証明と関連付けました。これは、インタラクティブな定理証明への新しいアプローチにつながり、その後の関数型プログラミング言語の開発に影響を与えました。[要出典]

David Turnerによって開発された怠惰な関数型言語Mirandaは、1985年に最初に登場し、 Haskellに強い影響を与えましたミランダがプロプライエタリであるため、Haskellは1987年に関数型プログラミング研究のオープンスタンダードを形成するためのコンセンサスから始めました。実装リリースは1990年から継続されています。

最近では、CSGジオメトリフレームワーク上に構築されたOpenSCAD言語のおかげでパラメトリックCADなどのニッチで使用されるようになりましたが、値の再割り当て(すべての値は定数として扱われる)の制限により、関数型プログラミングに慣れていないユーザーの間で混乱が生じています。概念として。[47]

関数型プログラミングは、商業環境で引き続き使用されています。[48] [49] [50]

コンセプト

多くの概念とパラダイムは関数型プログラミングに固有であり、一般に命令型プログラミングオブジェクト指向プログラミングを含む)とは無関係です。ただし、プログラミング言語は多くの場合、いくつかのプログラミングパラダイムに対応しているため、「ほとんど必須の」言語を使用するプログラマーは、これらの概念のいくつかを利用している可能性があります。[51]

一流以上の関数

高階関数は、他の関数を引数として受け取るか、結果として返すことができる関数です。微積分では、高階関数の例は微分演算子です 、関数の導関数を返します

高階関数は、高階関数と第一級関数の両方が引数としての関数と他の関数の結果を許可するという点で、第一級関数と密接に関連しています。2つの違いは微妙です。「高階」は他の関数で動作する関数の数学的概念を表し、「ファーストクラス」は使用に制限のないプログラミング言語エンティティのコンピュータサイエンス用語です(したがって、最初の-クラス関数は、他の関数への引数や戻り値など、数値などの他のファーストクラスエンティティが表示できるプログラム内のどこにでも表示できます。

高階関数は、部分適用またはカリー化を可能にします。これは、関数を一度に1つずつ引数に適用し、各アプリケーションが次の引数を受け入れる新しい関数を返す手法です。これにより、プログラマーは、たとえば、自然数1に部分的に適用される加算演算子として後継関数を簡潔に表現できます。

純粋関数

純粋関数(または式)には副作用(メモリまたはI / O)はありません。これは、純粋関数にはいくつかの有用なプロパティがあり、その多くを使用してコードを最適化できることを意味します。

  • 純粋な式の結果を使用しない場合は、他の式に影響を与えることなく削除できます。
  • 副作用を引き起こさない引数を使用して純粋関数を呼び出すと、結果はその引数リストに関して一定になります(参照透過性またはべきと呼ばれることもあります)。つまり、同じ引数を使用して純粋関数を再度呼び出すと、同じ結果が返されます。(これにより、メモ化などのキャッシュの最適化が可能になります。)
  • 2つの純粋な式の間にデータの依存関係がない場合は、順序を逆にするか、並行して実行して相互に干渉することはできません(つまり、純粋な式の評価はスレッドセーフです)。
  • 言語全体で副作用が許容されない場合は、任意の評価戦略を使用できます。これにより、コンパイラーは、プログラム内の式の評価を並べ替えたり組み合わせたりすることができます(たとえば、deforestationを使用します)。

命令型プログラミング言語のほとんどのコンパイラは純粋関数を検出し、純粋関数呼び出しに対して共通部分式除去を実行しますが、通常この情報を公開しないプリコンパイル済みライブラリに対して常にこれを実行できるとは限らないため、これらの外部関数を含む最適化が妨げられます。gccなどの一部のコンパイラーは、プログラマーが外部関数を純粋として明示的にマークするための追加のキーワードを追加して、そのような最適化を可能にします。Fortran 95では、関数を純粋に指定することもできます[52] C ++ 11はconstexpr、同様のセマンティクスを持つキーワードを追加しました。

再帰

関数型言語での反復(ループ)は通常、再帰を介して実行されます。再帰関数はそれ自体を呼び出し、基本ケースに到達するまで操作を繰り返します。一般に、再帰ではスタックを維持する必要があります。スタックは、再帰の深さに比例してスペースを消費します。これにより、命令型ループの代わりに再帰を使用すると、非常にコストがかかる可能性があります。ただし、末尾再帰と呼ばれる特殊な形式の再帰は、コンパイラーによって、命令型言語での反復の実装に使用されるのと同じコードに認識および最適化できます。末尾再帰の最適化は、プログラムを継続渡しスタイルに変換することで実装できます。他のアプローチの中でも、コンパイル中。

Scheme言語標準では、適切な末尾再帰をサポートする実装が必要です。つまり、無制限の数のアクティブな末尾呼び出しを許可する必要があります[53] [54]適切な末尾再帰は、単なる最適化ではありません。これは、再帰を使用してループを表現できることをユーザーに保証する言語機能であり、そうすることでスペースを確保できます。[55]さらに、その名前とは反対に、末尾再帰だけでなく、すべての末尾呼び出しを説明します。通常、適切な末尾再帰はコードを命令ループに変換することで実装されますが、実装では他の方法で実装される場合があります。たとえば、CHICKENは意図的にスタックを維持し、スタックをオーバーフローさせます。ただし、これが発生すると、ガベージコレクターはスペースバックを要求し[56]、末尾再帰をループに変えなくても、無制限の数のアクティブな末尾呼び出しを許可します。

再帰の一般的なパターンは、高階関数を使用して抽象化できます。最も明白な例は、カタモルフィズムアナモルフィズム(または「フォールド」と「アンフォールド」)です。このような再帰スキームは、命令型言語のループなどの組み込みの制御構造に類似した役割を果たします

ほとんどの汎用関数型プログラミング言語は、無制限の再帰を許可し、チューリング完全であるため、停止問題を 決定不能にし、方程式の推論の不健全さを引き起こす可能性があり、一般に、言語の型システムによって表現されるロジックに矛盾を導入する必要があります。Coqなどの一部の特殊目的言語は、十分に根拠のある再帰のみを許可し、強力に正規化しています(非終了の計算は、 codataと呼ばれる値の無限ストリームでのみ表現できます))。結果として、これらの言語はチューリング完全ではなく、特定の関数を表現することは不可能ですが、無制限の再帰によって生じる問題を回避しながら、幅広いクラスの興味深い計算を表現できます。他のいくつかの制約がある十分に根拠のある再帰に限定された関数型プログラミングは、全関数型プログラミングと呼ばれます。[57]

厳密な評価と非厳密な評価

関数型言語は、厳密な(熱心な)評価と厳密でない(遅延)評価のどちらを使用するかによって分類できます。これは、式の評価時に関数の引数がどのように処理されるかを示す概念です。技術的な違いは、失敗した計算または発散した計算を含む式の表示的意味論にあります。厳密な評価の下では、失敗したサブタームを含むタームの評価は失敗します。たとえば、次の式を使用します。

印刷長([2 + 1、3 * 2、1 / 0、5-4])

リストの3番目の要素がゼロで除算されているため、厳密な評価では失敗します。遅延評価では、長さ関数は値4(つまり、リスト内のアイテムの数)を返します。これは、評価がリストを構成する用語を評価しようとしないためです。簡単に言うと、厳密な評価では、関数を呼び出す前に常に関数の引数を完全に評価します。遅延評価は、関数呼び出し自体を評価するために値が必要でない限り、関数の引数を評価しません。

関数型言語での遅延評価の通常の実装戦略は、グラフ還元です。[58]遅延評価は、MirandaCleanHaskellなどのいくつかの純粋関数型言語でデフォルトで使用されます。

Hughes 1984は、データストリームのプロデューサーとコンシューマーの独立した実装を容易にすることにより、関心の分離を通じてプログラムのモジュール性を改善するメカニズムとして遅延評価を主張しています。[2] Launchbury 1993は、特にプログラムのストレージ要件の分析において遅延評価がもたらすいくつかの問題を説明し、そのような分析を支援するための操作的意味論を提案しています。[59] Harper 2009は、言語の型システムを使用してそれらを区別し、同じ言語で厳密な評価と遅延評価の両方を含めることを提案しています。[60]

型システム

特に1970年代にHindley-Milner型推論が開発されて以来、関数型プログラミング言語は型付きラムダ計算を使用する傾向があり、コンパイル時にすべての無効なプログラムを拒否し、型なしラムダ計算とは対照的に、誤検出エラーのリスクがあります。コンパイル時にプログラムが発生し、Lispとそのバリアント(Schemeなど)で使用されるフォールスネガティブエラーのリスクがあります。これは、情報が有効なプログラムを拒否しないのに十分な場合、実行時にすべての無効なプログラムを拒否するためです。代数的データ型の使用複雑なデータ構造の操作を便利にします。強力なコンパイル時の型チェックが存在することで、テスト駆動開発などの他の信頼性手法がない場合でもプログラムの信頼性が高まります。一方、型推論により、ほとんどの場合、コンパイラに型を手動で宣言する必要がなくなります。

CoqAgdaCayenneEpigramなどの一部の研究指向の関数型言語は、直観主義型理論に基づいており、型を用語に依存させることができます。このような型は依存型と呼ばれますこれらの型システムには決定可能な型推論がなく、理解してプログラミングするのは困難です。[61] [62] [63] [64]しかし、依存型は高階述語論理で任意の命題を表現できます。カリー・ハワード同形性により、これらの言語で適切に入力されたプログラムは、正式な数学的証明を作成する手段になります。コンパイラはそこから認定コードを生成できます。これらの言語は主に学術研究(形式化された数学を含む)に関心がありますが、工学でも使用され始めています。Compcertは、Coqで記述され、フォーマル検証されたCプログラミング言語のサブセット用のコンパイラです。[65]

一般化代数的データ型(GADT)と呼ばれる限定された形式の依存型は、その不便さのほとんどを回避しながら、依存型プログラミングの利点のいくつかを提供する方法で実装できます。[66] GADTは、Glasgow HaskellコンパイラOCaml [67]Scala [68]で利用可能であり、JavaやC#などの他の言語への追加として提案されています。[69]

参照透過性

関数型プログラムには代入ステートメントがありません。つまり、関数型プログラムの変数の値は、一度定義されると変更されることはありません。これにより、実行の任意の時点で任意の変数を実際の値に置き換えることができるため、副作用の可能性が排除されます。したがって、関数型プログラムは参照透過性があります。[70]

C代入ステートメントを考えてみましょうx = x * 10。これにより、変数に割り当てられた値が変更されますxの初期値がでxあったとすると1、変数の2つの連続した評価はそれぞれとをx生成10100ます。明らかに、またはのx = x * 10いずれかに置き換えると10100プログラムに別の意味が与えられるため、式参照透過性ではありません。実際、代入ステートメントは参照透過性ではありません。

ここで、入力xを暗黙的に変更せず、したがってそのような副作用がないため、transparentなどの別の関数について考えてみます関数型プログラムはこのタイプの関数のみを使用するため、参照透過性があります。 int plusone(int x) {return x+1;}

データ構造

純粋関数のデータ構造は、多くの場合、命令型のデータ構造とは異なる方法で表されます。[71]たとえば、アクセス時間と更新時間が一定の配列は、ほとんどの命令型言語の基本コンポーネントであり、ハッシュテーブルバイナリヒープなどの多くの命令型データ構造は配列に基づいています。配列は、マップまたはランダムアクセスリストに置き換えることができます。これらは、純粋に機能的な実装を認めますが、対数アクセスと更新時間を持ちます。純粋関数のデータ構造には永続性があります、以前のバージョンのデータ構造を変更せずに保持するプロパティ。Clojureでは、永続的なデータ構造が、必須の対応物の機能的な代替手段として使用されます。たとえば、永続的なベクトルは、部分的な更新にツリーを使用します。insertメソッドを呼び出すと、すべてではありませんが一部のノードが作成されます。[72]

命令型プログラミングとの比較

関数型プログラミングは命令型プログラミングとは大きく異なります最も重要な違いは、関数型プログラミングが、状態とI / Oを実装するための命令型プログラミングで使用される副作用を回避するという事実に起因します。純粋関数型プログラミングは、副作用を完全に防ぎ、参照透過性を提供します。

高階関数は、古い命令型プログラミングではめったに使用されません。従来の命令型プログラムでは、ループを使用してリストをトラバースおよび変更する場合があります。一方、関数型プログラムは、関数とリストを受け取り、各リストアイテムに関数を適用することで新しいリストを生成して返す、高階の「マップ」関数を使用する可能性があります。

命令型プログラミングと関数型プログラミング

次の2つの例(JavaScriptで記述)は同じ効果を実現します。配列内のすべての偶数に10を掛けてすべて加算し、最終的な合計を変数「result」に格納します。

従来の命令ループ:

const  numList  =  [ 1、2、3、4、5、6、7、8、9、10 ] ; _  _ _  _ _  _ _  _ _  _ _ _ _ _ _ _ _ 結果= 0とます; for let i = 0 ; i < numList。length ; i ++ { if numList [ i ] 2 === 0 { _ _    
   
         
        
    結果 + =  numList [ i ]  *  10 ; 
  } 
}

高階関数を使用した関数型プログラミング:

const  result  =  [ 1、2、3、4、5、6、7、8、9、10 ] _  _ _  _ _  _ _  _ _  _ _ _ _ _ _ _ _ _ フィルタn => n 2 === 0 マップa => a * 10 削減((a b => a + b );    
                     
                   
                    

状態のシミュレーション

多くの場合、州で最も自然に実装されているように見えるタスク(たとえば、銀行口座の残高の維持)があります。純粋関数型プログラミングは、これらのタスクと、ユーザー入力の受け入れや画面への印刷などのI / Oタスクを別の方法で実行します。

純粋な関数型プログラミング言語Haskellは、圏から派生したモナドを使用してそれらを実装しますモナドは、純度を失うことなく、命令型の方法で可変状態(およびI / Oなどの他の副作用)を使用した計算のモデリングを含む(ただしこれらに限定されない)特定のタイプの計算パターンを抽象化する方法を提供します。適切なテンプレートと例があれば、既存のモナドをプログラムに適用するのは簡単かもしれませんが、多くの学生は、新しいモナドを定義するように求められた場合など、概念的に理解するのが難しいと感じています(特定の種類のライブラリで必要になる場合があります)。[73]

関数型言語は、不変の状態を渡すことによって状態をシミュレートします。これは、関数がそのパラメーターの1つとして状態を受け入れ、結果とともに新しい状態を返し、古い状態を変更しないようにすることで実行できます。[74]

不純な関数型言語には通常、可変状態を管理するためのより直接的な方法が含まれています。たとえば、Clojureは、純粋関数を現在の状態に適用することで更新できるマネージド参照を使用します。この種のアプローチは、計算を表現するための好ましい方法として純粋関数の使用を促進しながら、可変性を可能にします。[要出典]

プログラムの副作用を追跡するために、ホーア論理一意性などの代替方法が開発されました。いくつかの現代の研究言語は、副作用の存在を明確にするためにエフェクトシステムを使用しています。[要出典]

効率の問題

関数型プログラミング言語は、通常、 CPascalなどの命令型言語よりもCPUとメモリの使用効率が低くなります[75] これは、配列などの一部の可変データ構造が、現在のハードウェアを使用した非常に単純な実装であるという事実に関連しています。フラットアレイは、深くパイプライン化されたCPUを使用して非常に効率的にアクセスでき、キャッシュを介して効率的にプリフェッチされます(複雑なポインター追跡は必要ありません)。)、またはSIMD命令で処理されます。また、同等に効率的な汎用の不変の対応物を作成することも容易ではありません。純粋関数型言語の場合、最悪の場合の速度低下は、使用されるメモリーセルの数の対数です。これは、可変メモリは、対数アクセス時間のある純粋関数型データ構造(平衡ツリーなど)で表すことができるためです。[76]しかしながら、そのような減速は普遍的ではない。Computer Language Benchmarks Gameによると、集中的な数値計算を実行するプログラムの場合、OCamlCleanなどの関数型言語はCよりもわずかに遅いだけです。[77]大きな行列と多次元を処理するプログラムの場合データベース配列関数型言語(JKなど)は、速度を最適化して設計されました。

多くの場合、データの不変性は、コンパイラーが命令型言語では安全ではない仮定を行うことを可能にすることで実行効率につながる可能性があり、したがってインライン展開の機会が増えます。[78]

遅延評価は、漸近的にもプログラムを高速化する可能性がありますが、最大でも一定の係数で速度を低下させる可能性があります(ただし、不適切に使用するとメモリリークが発生する可能性があります)。Launchbury 1993 [59]は、遅延評価からのメモリリークに関連する理論上の問題について説明しています2008 [79]は、それらを分析および修正するための実用的なアドバイスを提供します。ただし、逆参照されたコードとデータを多用する遅延評価の最も一般的な実装は、深いパイプラインとマルチレベルキャッシュ(キャッシュミスが数百サイクルかかる可能性がある)を備えた最新のプロセッサではパフォーマンスが低下します[要出典]

非関数型言語での関数型プログラミング

従来は関数型言語とは見なされていなかった言語で、関数型プログラミングを使用することができます。[80]たとえば、D [81]Fortran95 [52]はどちらも純粋関数を明示的にサポートしています。

JavaScriptLua[82] PythonGo [83]は、最初からファーストクラスの関数を持っていました。[84] Pythonは、1994年に「lambda」、「map」、「reduce」、「filter」をサポートし、Python 2.2ではクロージャをサポートしていましたが、[85] Python3は「reduce」をfunctools標準ライブラリモジュールに降格しました。[86]ファーストクラスの関数は、 PHP 5.3、Visual Basic 9C# 3.0、C ++ 11などの他の主流言語に導入されていますKotlin[27] [要出典]

PHPでは匿名クラスクロージャ、ラムダが完全にサポートされています。機能的なスタイルでのプログラミングを支援するために、不変のデータ構造用のライブラリと言語拡張が開発されています。

Javaでは匿名クラスを使用してクロージャをシミュレートできる場合があります[87]ただし、匿名クラスは機能が制限されているため、クロージャの適切な代替とは限りません。[88] Java 8は、一部の匿名クラスの代わりとしてラムダ式をサポートしています。[89]

C#では、クロージャとラムダが完全にサポートされているため匿名クラスは必要ありません。不変のデータ構造用のライブラリと言語拡張機能は、C#の機能スタイルでのプログラミングを支援するために開発されています。

多くのオブジェクト指向の デザインパターンは、関数型プログラミングの用語で表現できます。たとえば、戦略パターンは単に高階関数の使用を指示し、ビジターパターンは大まかにカタモルフィズムまたはフォールドに対応します。

同様に、関数型プログラミングからの不変データのアイデアは、命令型プログラミング言語[90]、たとえば不変配列であるPythonのタプルやJavaScriptのObject.freeze()に含まれることがよくあります。[91]

アプリケーション

スプレッドシート

スプレッドシートは、純粋なゼロ次の厳密な評価関数型プログラミングシステムの形式と見なすことができます。[92]ただし、スプレッドシートは一般に高階関数とコードの再利用を欠いており、一部の実装では再帰も欠いています。高次で再利用可能な機能を可能にするために、スプレッドシートプログラム用にいくつかの拡張機能が開発されましたが、これまでのところ、主に学術的な性質を保っています。[93]

アカデミア

関数型プログラミングは、プログラミング言語理論の分野で活発に研究されている分野です関数型プログラミングに関する国際会議、関数型プログラミングジャーナル、関数型プログラミングの動向に関するシンポジウムなど、関数型プログラミングに焦点を当てた査読付きの出版物がいくつかあります

業界

関数型プログラミングは、さまざまな産業用アプリケーションで使用されています。たとえば、1980年代後半にスウェーデンの企業Ericssonによって開発されたErlangは、もともとフォールトトレラントな通信システムを実装するために使用されていましたが[11] 、その後NortelFacebookなどの企業でさまざまなアプリケーションを構築するために人気があります。ÉlectricitédeFranceおよびWhatsApp[10] [12] [94] [95] [96]スキームLispの方言 は、初期のAppleMacintoshコンピュータのいくつかのアプリケーションの基礎として使用され[3] [4] 、シミュレーションソフトウェアのトレーニング[5]望遠鏡の制御などの問題に適用されてきました。[6] 1990年代半ばに導入されたOCamlは、財務分析、 [14] ドライバー検証、産業用ロボットプログラミング、組み込みソフトウェアの静的分析などの分野で商用利用されています[15] Haskellは、当初は研究言語として意図されていたが、[17]また、航空宇宙システム、ハードウェア設計、Webプログラミングなどの分野で、さまざまな企業から適用されています。[16] [17]

業界で使用されている他の関数型プログラミング言語には、Scala[97] F#[18] [19] Wolfram Language[7] Lisp[98] Standard ML[99] [100]Clojureなどがあります。[101]

機能的な「プラットフォーム」は、リスク分析のための金融で人気があります(特に大規模な投資銀行で)。リスク要因は、相互依存グラフ(カテゴリ)を形成する関数としてコード化され、グレブナー基底の最適化とは異なり、包括的資本分析やレビューなどの規制コンプライアンスのために、市場シフトの相関関係を測定します。財務におけるOCAMLまたはCAMLのバリエーションの使用を考えると、これらのシステムは、カテゴリ別の抽象マシンまたはCAMに関連していると見なされることがあります。実際、関数型プログラミングは圏論の影響を強く受けています

教育

多くの大学は、学部のコンピュータサイエンスの学位の一部として関数型プログラミングを教えているか、教えてきました。[102] [103] [104] [105]プログラミングの入門書として使用する人もいれば、[105]命令型プログラミングを教えた後に教える人もいます。[104] [106]

コンピュータサイエンス以外では、関数型プログラミングは、問題解決、代数、幾何学の概念を教える方法として使用されています。[107]それはまた、古典力学の構造と解釈において古典 力学を教えるためのツールとしても使用されてきました

も参照してください

参考文献

  1. ^ Hudak、Paul(1989年9月)。「関数型プログラミング言語の概念、進化、および応用」(PDF)ACMコンピューティング調査21(3):359–411。土井10.1145 /72551.72554S2CID207637854_  
  2. ^ a b ヒューズ、ジョン(1984)。「関数型プログラミングが重要な理由」
  3. ^ a b Clinger、Will(1987)。「マルチタスクとMacScheme」MacTech3(12)2008年8月28日取得
  4. ^ a b Hartheimer、Anne(1987)。「MacScheme + Toolsmithでのテキストエディタのプログラミング」MacTech3(1)。2011年6月29日にオリジナルからアーカイブされました2008年8月28日取得
  5. ^ a b キッド、エリック。スキームにおけるテロ対応訓練CUFP2007 2009年8月26日取得
  6. ^ a b Cleis、リチャード。宇宙でのスキームCUFP2006 2009年8月26日取得
  7. ^ a b 「Wolfram言語ガイド:関数型プログラミング」2015 2015年8月24日取得
  8. ^ 「関数型プログラミング言語と手続き型プログラミング言語」応用数学科コロラド大学。2007年11月13日にオリジナルからアーカイブされました
  9. ^ 「未知の2の状態ベースのスクリプティング」(PDF)2012年12月15日にオリジナル(PDF)からアーカイブされました2011年8月8日取得
  10. ^ a b 「製品開発にErlangを使用しているのは誰ですか?」Erlangに関するよくある質問2018年4月27日取得
  11. ^ a b アームストロング、ジョー(2007年6月)。Erlangの歴史プログラミング言語の歴史に関する第3回ACMSIGPLAN会議。カリフォルニア州サンディエゴ。土井10.1145 /1238844.1238850
  12. ^ a b Larson、Jim(2009年3月)。「並行プログラミングのためのErlang」ACMの通信52(3):48。doi10.1145 /1467247.1467263S2CID524392_ 
  13. ^ 「Elixirプログラミング言語」2021-02-14を取得
  14. ^ a b ミンスキー、ヤロン; 週、スティーブン(2008年7月)。「CamlTrading—ウォール街での関数型プログラミングの経験」機能プログラミングジャーナル18(4):553–564。土井10.1017 / S095679680800676XS2CID30955392 _ 2008年8月27日取得 
  15. ^ a b リロイ、ザビエル。産業におけるCamlのいくつかの使用法(PDF)CUFP2007 2009年8月26日取得
  16. ^ a b "業界のHaskell"HaskellWiki 2009年8月26日取得Haskellは、航空宇宙や防衛から金融、Webスタートアップ、ハードウェア設計会社、芝刈り機メーカーまで、商業的に多様な用途を持っています。
  17. ^ a b c Hudak、Paul ; ヒューズ、J。; ジョーンズ、SP; Wadler、P。(2007年6月)。Haskellの歴史:クラスで怠惰であることプログラミング言語の歴史に関する第3回ACMSIGPLAN会議。カリフォルニア州サンディエゴ。土井10.1145 /1238844.1238856 2013年9月26日取得
  18. ^ a b マンセル、ハワード(2008)。F#の定量的ファイナンスCUFP2008 2009年8月29日取得
  19. ^ a b Peake、Alex(2009)。F#の最初の実質的な基幹業務アプリケーションCUFP2009。2009-10-17のオリジナルからアーカイブ2009年8月29日取得
  20. ^ コメント、2017年6月27日Matt Banz Feed 603up2。「JavaScriptでの関数型プログラミングの概要」Opensource.com 2021-01-09を取得
  21. ^ 「useR!2006の会議スケジュールには、Rの商用利用に関する論文が含まれています」R-project.org。2006-06-08 2011年6月20日取得
  22. ^ チェンバーズ、ジョンM.(1998)。データを使用したプログラミング:S言語のガイドシュプリンガーバーラグ。pp。67–70。ISBN 978-0-387-98503-9
  23. ^ Novatchev、Dimitre。「関数型プログラミング言語XSLT—例による証明」2006年5月27日取得
  24. ^ メルツ、デビッド。「XMLプログラミングパラダイム(パート4):XML処理にアプローチする関数型プログラミング」IBMdeveloperWorks 2006年5月27日取得
  25. ^ チェンバリン、ドナルドD。; ボイス、レイモンドF.(1974)。「SEQUEL:構造化された英語のクエリ言語」。1974 ACM SIGFIDETの議事録:249–264。
  26. ^ C#を使用した関数型プログラミング -Simon Painter-NDC Oslo 2020、2021-10-30にオリジナルからアーカイブ、2021-10-23を取得
  27. ^ a b "関数型プログラミング-Kotlinプログラミング言語"Kotlin 2019-05-01を取得しました。
  28. ^ Dominus、Mark J.(2005)。高次PerlモーガンカウフマンISBN 978-1-55860-701-9
  29. ^ Holywell、Simon(2014)。PHPでの関数型プログラミングphp [アーキテクチャ]。ISBN 9781940111056
  30. ^ The Cain Gang Ltd. 「Pythonメタクラス:誰?なぜ?いつ?」(PDF)2009年5月30日にオリジナル(PDF)からアーカイブされました2009年6月27日取得
  31. ^ 「GopherCon2020:DylanMeeus-Goを使用した関数型プログラミング」YouTube.com{{cite web}}:CS1 maint:url-status(link
  32. ^ 「関数型言語の機能:イテレータとクロージャ-Rustプログラミング言語」doc.rust-lang.org 2021-01-09を取得
  33. ^ Vanderbauwhede、Wim。「関数型プログラミングによるよりクリーンなコード」2020年9月11日にオリジナルからアーカイブされました2020年10月6日取得
  34. ^ 「効果的なScala」ScalaWiki 2012年2月21日取得効果的なScala。
  35. ^ 「Java8(Java 1.8とも呼ばれます)以降のパッケージjava.util.functionのドキュメント」2021-06-16を取得
  36. ^ チューリング、AM(1937)。「計算可能性とλ定義可能性」。シンボリックロジックのジャーナルケンブリッジ大学出版局。2(4):153–163。土井10.2307 / 2268280JSTOR2268280_ 
  37. ^ ハスケルブルックスカリー; ロベール・フェイ(1958)。コンビネータ論理North-Holland PublishingCompany 2013年2月10日取得
  38. ^ 教会、A。(1940)。「型の単純な理論の定式化」。Journal of SymbolicLogic5(2):56–68。土井10.2307 / 2266170JSTOR2266170_ 
  39. ^ マッカーシー、ジョン(1978年6月)。Lispの歴史(PDF)プログラミング言語の歴史カリフォルニア州ロサンゼルス。pp。173–185。土井10.1145 /800025.808387
  40. ^ ジョンマッカーシー(1960)。「S式の再帰関数とその機械による計算、パートI」(PDF)ACMの通信ACMニューヨーク、ニューヨーク、米国。3(4):184–195。土井10.1145 /367177.367199S2CID1489409_  
  41. ^ ガイ・L・スティール; リチャードP.ガブリエル(1996年2月)。Lispの進化(PDF)ACM / SIGPLANのプログラミング言語の第2の歴史pp。233–330。土井10.1145 /234286.1057818ISBN  978-0-201-89502-5S2CID47047140 _
  42. ^ ハーバート・A・サイモンの回想録(1991)、私の人生のモデルpp.189-190 ISBN 0-465-04640-1は、彼、アル・ニューウェル、クリフ・ショーが「...一般的に両親であると判断されている」と主張していますPrincipiaMathematicaの定理を自動的に証明するプログラムであるLogicTheoristを作成するための人工知能[フィールド]のこれを達成するために、彼らは、遡及的に見て、関数型プログラミングを組み込む言語とパラダイムを発明しなければなりませんでした。 
  43. ^ Backus、J。(1978)。「プログラミングをノイマン型から解放できるか?:機能的なスタイルとそのプログラムの代数」ACMの通信21(8):613–641。土井10.1145 /359576.359579
  44. ^ RMバーストール。関数型プログラミング言語の設計上の考慮事項。招待論文、Proc。Infotech State of the ArtConf。「TheSoftwareRevolution」、コペンハーゲン、45–57(1977)
  45. ^ RMバーストールとJ.ダーリントン。再帰的プログラムを開発するための変換システム。Journal of the Association for Computing Machinery 24(1):44–67(1977)
  46. ^ RM Burstall、DB MacQueen、DTSannella。HOPE:実験的な応用言語。Proc。1980 LISP会議、スタンフォード、136–143(1980)。
  47. ^ 「assign()の検出を簡単にします!」OpenSCAD
  48. ^ ピーターブライト(2018年3月13日)。「開発者は流行の新しい言語が大好きですが、関数型プログラミングでより多くの収入を得ることができます」ArsTechnica
  49. ^ ジョンレナード(2017年1月24日)。「関数型プログラミングのステルスな台頭」コンピューティング。
  50. ^ Leo Cheung(2017年5月9日)。「関数型プログラミングはあなたのスタートアップにとってより良いですか?」InfoWorld
  51. ^ 噴水、ディック。「関数型プログラミングは時代を迎える」BYTE.com(1994年8月)2006年8月27日にオリジナルからアーカイブされました2006年8月31日取得
  52. ^ a b "ISO / IEC JTC 1 / SC 22 / WG5 / N2137"国際標準化機構。2017年7月6日。 {{cite journal}}引用ジャーナルには|journal=ヘルプ)が必要です
  53. ^ 「アルゴリズム言語スキームに関する改訂^ 6レポート」R6rs.org 2013年3月21日取得
  54. ^ 「アルゴリズム言語スキームに関する改訂^ 6レポート-理論的根拠」R6rs.org 2013年3月21日取得
  55. ^ クリンガー、ウィリアム(1998)。「適切な末尾再帰とスペース効率」。プログラミング言語の設計と実装に関するACMSIGPLAN1998会議の議事録-PLDI'98pp。174–185。土井10.1145 /277650.277719ISBN 0897919874S2CID16812984 _
  56. ^ ベイカー、ヘンリー(1994)。「CONSはその議論をCONSすべきではない、パートII:MTAのチェイニー」
  57. ^ ターナー、DA(2004-07-28)。「トータル関数型プログラミング」ユニバーサルコンピュータサイエンスジャーナル10(7):751〜768。土井10.3217 / jucs-010-07-0751
  58. ^ 関数型プログラミング言語の実装サイモンペイトンジョーンズ、プレンティスホール発行、1987年
  59. ^ a b ジョン・ラウンチベリー(1993)。「遅延評価のための自然な意味論」。CiteSeerX10.1.1.35.2016_  {{cite journal}}引用ジャーナルには|journal=ヘルプ)が必要です
  60. ^ ロバートW.ハーパー(2009)。プログラミング言語の実用的な基礎(PDF)2016年4月7日にオリジナル(PDF)からアーカイブされました
  61. ^ Huet、GérardP。(1973)。「3次論理における統一の決定不能性」。情報と管理22(3):257–267。土井10.1016 / s0019-9958(73)90301-x
  62. ^ ジェラール・ヒュエット(1976年9月)。Resolution d'Equations dans des Langages d'Ordre 1,2、...ω(Ph.D。)(フランス語)。パリ大学VII。
  63. ^ Huet、Gérard(2002)。「30年後の高階統一」(PDF)カレニョでは、V。; ムニョス、C。; タハール、S。(編)。議事録、第15回国際会議TPHOLLNCS。2410.スプリンガー。pp。3–12。
  64. ^ ウェルズ、JB(1993)。「2次ラムダ計算での型付け可能性と型チェックは同等であり、決定不可能です」。Tech。担当者93-011CiteSeerX10.1.1.31.3590_ 
  65. ^ リロイ、ザビエル(2018年9月17日)。「Compcert検証済みコンパイラ」
  66. ^ ペイトン・ジョーンズ、サイモン; Vytiniotis、Dimitrios; ワイリッヒ、ステファニー; ジェフリーウォッシュバーン(2006年4月)。「GADTの単純な統合ベースの型推論」ICFP 2006:50–61。
  67. ^ 「OCamlマニュアル」caml.inria.fr 2021-03-08を取得{{cite web}}:CS1 maint:url-status(link
  68. ^ 「代数的データ型」Scalaドキュメント2021-03-08を取得
  69. ^ ケネディ、アンドリュー; ルッソ、クラウディオ(2005年10月)。一般化された代数的データ型とオブジェクト指向プログラミング(PDF)OOPSLAカリフォルニア州サンディエゴ。ISBN  97815959303162006年12月29日にオリジナル (PDF)からアーカイブされました 引用元
  70. ^ ヒューズ、ジョン。「関数型プログラミングが重要な理由」(PDF)チャルマース工科大学
  71. ^ Chris Okasakiによる純粋関数型データ構造ケンブリッジ大学出版局、1998年、 ISBN 0-521-66350-4 
  72. ^ L'orange、Jean Niklas "polymatheia-Clojureの永続的なベクトルを理解する、pt。1"ポリマテイア2018年11月13日取得
  73. ^ Newbern、J。「モナドのすべて:Haskellでのモナドプログラミングの理論と実践への包括的なガイド」2008年2月14日取得
  74. ^ 「カメを見る13の方法」楽しさと利益のためのfF#2018年11月13日取得
  75. ^ Paulson、Larry C.(1996年6月28日)。働くプログラマーのためのMLケンブリッジ大学出版局。ISBN 978-0-521-56543-12013年2月10日取得
  76. ^ スピワック、ダニエル(2008年8月26日)。「Scalaでの永続的なベクトルの実装」コードコミット
  77. ^ 「どのプログラムが最速ですか?|コンピュータ言語ベンチマークゲーム」ベンチマークゲーム.alioth.debian.org。2013年5月20日にオリジナルからアーカイブされまし2011年6月20日取得
  78. ^ Igor Pechtchanski; Vivek Sarkar(2005)。「不変性仕様とその応用」。並行性と計算:実践と経験17(5–6):639–662。土井10.1002 /cpe.853S2CID34527406_ 
  79. ^ 「第25章。プロファイリングと最適化」Book.realworldhaskell.org 2011年6月20日取得
  80. ^ ハーテル、ピーター; ヘンク・ミュラー; ヒューグレイザー(2004年3月)。「ファンクショナルCエクスペリエンス」(PDF)機能プログラミングジャーナル14(2):129–135。土井10.1017 / S0956796803004817S2CID32346900_  ; デビッドメルツ。「Pythonでの関数型プログラミング、パート3」IBMdeveloperWorks2007年10月16日にオリジナルからアーカイブされまし2006年9月17日取得パート1パート2
  81. ^ 「関数—Dプログラミング言語2.0」デジタル火星。2012年12月30日。
  82. ^ 「Lua非公式FAQ(uFAQ)」
  83. ^ 「Goの第一級関数-Goプログラミング言語」golang.org 2021-01-04を取得
  84. ^ ブレンダン・アイク(2008年4月3日)。「人気」
  85. ^ ヴァンロッサム、グイド(2009-04-21)。「Pythonの「機能的な」機能の起源」2012年9月27日取得
  86. ^ 「functools—呼び出し可能なオブジェクトに対する高階関数と操作」Pythonソフトウェアファウンデーション。2011-07-31 2011年7月31日取得
  87. ^ Skarsaune、Martin(2008)。SICS Java Port Projectは、SmalltalkからJavaへのラージオブジェクト指向システムの自動翻訳です
  88. ^ ゴスリング、ジェームズ。「クロージャ」ジェームズ・ゴスリング:ジャバロードで。オラクル。2013年4月14日にオリジナルからアーカイブされまし2013年5月11日取得
  89. ^ ウィリアムズ、マイケル(2013年4月8日)。「JavaSE8Lambdaクイックスタート」
  90. ^ ブロッホ、ジョシュア(2008)。「項目15:可変性の最小化」。効果的なJava(第2版)。アディソン-ウェスリー。ISBN 978-0321356680
  91. ^ "Object.freeze()-JavaScript | MDN"developer.mozilla.org 2021-01-04を取得Object.freeze()メソッドはオブジェクトをフリーズします。凍結されたオブジェクトは変更できなくなりました。オブジェクトをフリーズすると、新しいプロパティがオブジェクトに追加されたり、既存のプロパティが削除されたり、既存のプロパティの列挙可能性、構成可能性、または書き込み可能性が変更されたり、既存のプロパティの値が変更されたりするのを防ぐことができます。さらに、オブジェクトをフリーズすると、そのプロトタイプが変更されるのを防ぐこともできます。freeze()は、渡されたのと同じオブジェクトを返します。{{cite web}}:CS1 maint:url-status(link
  92. ^ Wakeling、David(2007)。「スプレッドシート関数型プログラミング」(PDF)機能プログラミングジャーナル17(1):131–143。土井10.1017 / S0956796806006186ISSN0956-7968_ S2CID29429059_   
  93. ^ ペイトン・ジョーンズ、サイモン; バーネット、マーガレット; ブラックウェル、アラン(2003年3月)。「世界で最も人気のある関数型言語の改善:Excelのユーザー定義関数」2005-10-16にオリジナルからアーカイブされました。
  94. ^ Piro、クリストファー(2009)。Facebookでの関数型プログラミングCUFP2009。2009-10-17のオリジナルからアーカイブ2009年8月29日取得
  95. ^ 「Sim-Diasca:Erlangの大規模離散イベント並行シミュレーションエンジン」2011年11月。
  96. ^ 100万はそう2011 // WhatsAppブログ、2012-01-06:「私たちのインフラストラクチャの最後の重要な部分はErlangです」
  97. ^ Momtahan、Lee(2009)。EDF TradingでのScala:Scalaを使用したデリバティブ価格設定のためのドメイン固有言語の実装CUFP2009。2009-10-17のオリジナルからアーカイブ2009年8月29日取得
  98. ^ グラハム、ポール(2003)。「平均を破る」2009年8月29日取得
  99. ^ シムズ、スティーブ(2006)。Standard MLを使用したスタートアップの構築(PDF)CUFP2006 2009年8月29日取得
  100. ^ Laurikari、Ville(2007)。通信セキュリティにおける関数型プログラミングCUFP2007 2009年8月29日取得
  101. ^ Lorimer、RJ(2009年1月19日)。「LiveProductionClojureアプリケーションが発表されました」InfoQ
  102. ^ 「関数型プログラミング:2019-2020」オックスフォード大学コンピュータサイエンス学部2020年4月28日取得
  103. ^ 「プログラミングI(Haskell)」インペリアルカレッジロンドンコンピューティング学科2020年4月28日取得
  104. ^ a b "Computer Science BSc-Modules" 2020年4月28日取得
  105. ^ a b アベルソン、ハル; サスマン、ジェラルドジェイ(1985)。「第2版の序文」コンピュータプログラムの構造と解釈(2版)。MITプレス。
  106. ^ ジョンデネロ(2019年秋)。「コンピュータサイエンス61A、バークレー校」カリフォルニア大学バークレー校電気工学およびコンピュータサイエンス学科2020年8月14日取得
  107. ^ TWiT.tvネットワークのテレビ番組TriangulationでインタビューされたBootstrapのEmmanuelSchanzer

さらに読む

外部リンク

この記事を聞く28
音声ウィキペディアアイコン
このオーディオファイルは、2011年8月25日付けのこの記事の改訂版から作成されたものであり、その後の編集は反映されていません。 (2011-08-25)