「関数型プログラミング」の版間の差分
削除された内容 追加された内容
m Internal link written as an external link |
|||
(同じ利用者による、間の12版が非表示) | |||
2行目:
{{プログラミング言語|index=かんすうかたけんこ}}
[[ファイル:Orange_lambda.svg|代替文=|境界|右|フレームなし|167x167ピクセル]]
'''関数型
== 特徴 - 構文面 ==▼
[[数理論理学]]の[[ラムダ計算]]と[[LISP]]言語が主な土台になっている。
===
*関数型プログラムの[[文 (プログラミング)|基本文]]は[[式 (プログラミング)|式]](''expression'')である。式は値と同一視される。
*式は、値(''value'')と演算子(''operator'')と関数(''function'')で構成される。式内の代数部分が確定される前の式は抽象値と同義であり、確定後の式は実値と同義になる。ここでの代数とは式内の各束縛変数と、同じく式内の各関数の引数の双方を指す。実値の導出過程は評価(''evaluation'')と呼ばれる。
*式を評価した値の後続式への反映は変数への代入ではなく、[[束縛変数]]で定数化するのが本来の在り方である。
*{{仮リンク|暗黙プログラミング|en|tacit programming|label=}}が指向されており、直前の式の評価値はそのまま直後の式の適用値にする事もできる。これは[[パイプライン処理|パイプライン]]またはポイントフリーと呼ばれる。
*関数も値と同一視される。関数は引数(''argument'')と式を結び付けるユニットである。式の代数部分に引数値が順次束縛される。式も値なので、関数のフロー終端式がそのまま結果値になる。
*関数は、式の引数への適用(''applying'')と解釈される。その対義概念として反適用(''unapplying'')の仕組みも存在する。これは式の引数への適用を差し戻して元の引数を抽出する。
*関数は、式を第1引数に適用したもの→第2引数に適用したもの→第x引数に適用したもの→結果値、というような形をとる。関数の型は、各引数値から結果値までの型の連鎖として表現される。
*型の連鎖は、さながらパズルのような関数の断片化と連結を可能にする。前者は部分適用と呼ばれ、例えば式を第1引数に適用しただけのものを後続の式で使い回せる。後者は関数合成と呼ばれ、結果値と第1引数が同じ型の関数をつなげたものを後続の式で使い回せる。
*関数は名前付きと名前無しの二通りある。後者はラムダ抽象を模した構文で式中に直接定義される。これは[[クロージャ]]または[[無名関数]]と呼ばれる。
*関数は値と同義なので、関数の引数値を関数にする事も可能であり、また関数の結果値を関数にする事も可能である。関数を引数値または結果値として扱える関数は[[高階関数]]と呼ばれる。引数値または結果値として扱われる関数は[[第一級関数]]と呼ばれる。
*演算子はデフォルト式内容を持ち引数が1~2個に限定された関数と同義である。演算子の式内容は任意に変更できる。巷の演算子オーバーロードは関数型プログラミング由来と言える。
=== 値と型 ===
*値(''value'')は型(''type'')によって分類される。無数に存在する型同士の等価計算を円滑化する為に、型もまた型クラス(''type class'')あるいは型ヴァリアント(''type variant'')といった機能で分類される。これらの習合は[[型システム]]と呼ばれる。
=== 設計視点 ===▼
*型クラスは自身に属する型(=型インスタンス)の値が適用される演算子と関数を定義する。その式内容は型インスタンスの方で実装される。型クラスによる定義と実装の分離は型の多相を表現できる。
関数型プログラミングは[[宣言型プログラミング]](''declarative programming'')のカテゴリに属するパラダイムである。宣言型と対照的関係にあるのが[[命令型プログラミング]](''imperative programming'')であり、そのカテゴリには[[手続き型プログラミング]]と[[オブジェクト指向プログラミング]]などが属している。命令型と宣言型を分ける一つの基準は[[副作用 (プログラム)|副作用]](''side-effects'')に対する考え方および扱い方である。この副作用については改めて後述するが、簡潔に述べると現行プロセスの閉包領域の外にある様々な情報資源の状態=いわゆる「環境」の変化と、その変化によって各プロセスの処理過程もまた影響を受ける事を指す。ここでの情報資源とは、プログラムの各種入出力(I/O)を担う[[オペレーティングシステム]]の現行状態と、プログラムを走行させている[[仮想マシン|ランタイム環境]]が提供する各種データリソースを意味する。データリソースには純粋関数型では扱いにくい動的配列と動的連想配列も含まれる。▼
*型ヴァリアントは[[共用体]]に似た仕組みでそれぞれ異なる型の値をグループ化できる。これは[[パターンマッチング]]時に活用され柔軟(場合によっては無節操)な多分岐節を表現できる。
*値の型宣言は積極的に省略される。省略された型を導き出す機能は[[型推論]]と呼ばれる。これは決して簡略化のためではなく、与えられた初期値または引数値からの変換作業を履行するという関数型の性格上、省略する方が自然なスタイルになるからである。
*型は「A B」のように直列表現もされこれはモナド型(''monadic type'')と呼ばれる。AはB型値の背景情報(''context'')の型であり大抵の場合後述の[[副作用 (プログラム)|副作用]](''side-effect'')を包括する。型の直列は関数型プログラミングの要点になる[[モナド (プログラミング)|モナド]]の仕組みを表現する。
*モナド型からは概念的に反適用の仕組みによって値が抽出される。「A B」型の値からB型値を抜き出して次の式に適用させるといった具合である。パイプラインと同様に抽出も{{仮リンク|暗黙プログラミング|en|tacit programming|label=}}に則って自動解釈される事が多い。
*値は代数的データ(''algebraic data'')として表現される。代数的データは、''atom(プリミティブ)nil(無)cons(値+リンク)''の要素からなる。代数的データは''cons''の再帰で構成されており、ゼロ個から複数以上の値を内包する事になる。''cons''の値は''atom''または入れ子の代数的データを指し、''cons''のリンクは次の''cons''または''nil''を指す。''atom''は数値、論理値、文字、文字列を指す。この再帰ツリー構造は[[S式]]と呼ばれる。
*代数的データは単体値の表現でもあり、あらゆる値集合の原始的表現でもある。代数的データによって単値と値集合を同等に扱うスタイルが関数型プログラミングの代表的利点であるリスト処理([[イテレーション]])に繋がっている。
*代数的データは''cons''の再帰構造であり、先頭''cons''の値+リンクを常時分離表現できる。そのリンクは後続全''consを''表現する。そのリンクが指す''cons''を再帰関数の引数にして値+リンクを再度分離しそのまた再帰を繰り返していくと、結果的に代数的データの全内包値に作用を及ぼせる事になる。
*全ての値が同型の代数的データは''list''と呼ばれ、上述の''cons''の値+リンク分離と再帰関数の合わせ技による反復作用の典型的対象とされる。
*異なる型の値を内包した代数的データは''tuple''と呼ばれ、用法によっては[[構造体]](''data structure'')と同等になる。
=== 分岐と再帰 ===
*[[再帰]]が重視されている。関数の再帰呼び出しと[[相互再帰]]が多用される。データ定義でも、データ名に対する定義式の中で自身データ名が記述される再帰定義が多用される。
▲== 特徴 ==
*カウンタ変数を増減するループ文は用いられないのが本来の在り方である。同様の反復フローはカウンタ値を束縛変数にした関数の再帰で行う。
*引数値による多分岐節([[パターンマッチング]])が多用される。関数型プログラミングにおける選択フローは、引数の多分岐から始まる関数に集約される。
[[数理論理学]]の[[コンビネータ論理]]と[[圏論]]が主な土台になっている。
=== パラダイム ===
▲関数型プログラミングは[[宣言型プログラミング]]
===
=== 再帰と評価戦略
▲=== 純粋関数(''pure function'') ===
== 歴史 ==
|