「関数型プログラミング」の版間の差分

削除された内容 追加された内容
m Internal link written as an external link
編集の要約なし
2行目:
{{プログラミング言語|index=かんすうかたけんこ}}
[[ファイル:Orange_lambda.svg|代替文=|境界|右|フレームなし|167x167ピクセル]]
'''関数型プログラミング言語'''({{lang-en-short|''functional programming language''}})は、関数型プログラミングの[[プログラミングパラダイム|パラダイム]]を扱う[[プログラミング言語]]の総称である。'''純粋関数型'''(''purely functional'')と'''非純粋関数型'''(''impure functional'')の二つに大別され、後者の方が幅広く用いられている。[[マルチパラダイムプログラミング言語|マルチパラダイム言語]]に組み込まれているものは例外なく非純粋である。関数型プログラミングは構文(''syntax'')と設計(''design'')の二つの視点から解釈される。この双方に忠実なのが純粋関数型とされ、構文スタイルを中心に導入し、設計面にはそれほど忠実でないのが非純粋関数型とされる。
 
非純粋関数型は、関数を値として扱える[[高階関数]]、値として扱われる[[第一級関数]]、型を体系化ないし抽象化する[[型システム]]をそれぞれ連携させた計算式の構文スタイルに着目している部分が大きい。それに加えて純粋関数型は、プログラム概念上の[[副作用 (プログラム)|副作用]]をイメージ的に排除する[[参照透過性]]をプロセスの原則にしたものであり、その仕様実現の為に専用のランタイム環境上でプログラムは走行される。
 
== 概要 ==
 
=== 構文視点 ===
関数型プログラミングの基本要素である関数(''function'')とは、与えられた入力値から任意の出力値を導き出す変換式を意味するが、[[数理論理学]]の[[型付きラムダ計算]]がモデルにされてる背景からそれに加えた性質を持つ。関数はそれ自体が型付きの値として扱われるが、その「関数の型」は各引数値一つ一つへの適用から結果値までのパターンである型の連鎖として表現される。関数を値として扱える関数の仕組みは[[高階関数]](''higher-order function'')、値そのものとして扱われる関数の仕組みは[[第一級関数]](''first-class function'')と呼ばれる。型(''type'')を体系化ないし抽象化する仕組みは[[型システム]](''type system'')と呼ばれる。引数になった関数もまた引数を持つといった連鎖は広義の[[相互再帰]]になり[[複雑系]]のプロセスを自然に表現する。それらの連携による計算式のスタイルが関数型プログラミングをユニークなものにしている。
 
この[[ラムダ計算]]の論理を背景にした関数の用法を、一般的な手続き型プログラミングの視点から眺めると、手続き型では関数定義を識別する[[シグネチャ]]でしかなかった関数の「引数欄」を、関数型の方ではその順序構成に厳格に意味を持たせたプログラム要素にして「関数の型」の表現法に組み込んでいる点が大きな違いになる。高階、第一級関数に加えて、この引数欄構造の明確な有意義化が、[[カリー化]]と合わせたラムダ計算視点の式分析と、その論理に則った各種変換および各種簡約による式の再構成を可能にし、また部分適用や関数合成による式の組み換えも可能にして、式の平易化と関数アルゴリズムの最適化を実現している。
 
=== 設計視点 ===
関数型プログラミングは[[宣言型プログラミング]](''declarative programming'')のカテゴリに属するパラダイムである。宣言型と対照的関係にあるのが[[命令型プログラミング]](''imperative programming'')であり、そのカテゴリには[[手続き型プログラミング]]と[[オブジェクト指向プログラミング]]などが属している。命令型と宣言型を分ける一つの基準は[[副作用 (プログラム)|副作用]](''side-effects'')に対する考え方および扱い方である。この副作用については改めて後述するが、簡潔に述べると現行プロセスの閉包領域の外にある様々な情報資源の状態=いわゆる「環境」の変化と、その変化によって各プロセスの処理過程もまた影響を受ける事を指す。ここでの情報資源とは、プログラムの各種入出力(I/O)を担う[[オペレーティングシステム]]の現行状態と、プログラムを走行させている[[仮想マシン|ランタイム環境]]が提供する各種データリソースを意味する。データリソースには純粋関数型では扱いにくい動的配列と動的連想配列も含まれる。
 
命令型プログラミングは前述の「環境」に対して自由に作用を及ぼせるパラダイムであり、それが”''imperative''”の由来にもなっている。それに対して宣言型プログラミングは作用を及ぼせる対象と、自身がその影響を受ける事になる対象が、あらかじめ初期値または入力値として”''declarative''”された情報資源(=データ)のみに限られている。加えて関数型プログラミングは原則的に、宣言されたデータに対しても作用を及ぼさず、他の値を導き出す為の因子として扱う。
 
== 特徴 ==
関数型プログラミングを構成する考え方には以下のものがある。
 
=== 参照透過性(''referential transparency'') ===
 
=== データ機構(''data structure'') ===
 
=== 再帰(''recursion'') ===
 
=== 構文視点 ===
=== 評価戦略(''evaluation strategy'') ===
 
* [[数理論理学]]の[[ラムダ計算]]の哲学が土台になっている。通常のコーディングではそれほど意識する必要もないが、同じプログラムでもラムダ計算の原理が念頭にあるか否かでだいぶ見方も変わり、式の組み立てと拡張ないし平易化が促進される。
=== 型の体系(''type system'') ===
*プログラムの[[文 (プログラミング)|基本文]]は[[式 (プログラミング)|式]](''expression'')とされ、それ自体が値(''value'')と見なされている。式の値の後続式への反映は、変数への代入ではなく束縛変数(''bound variable'')への結び付けにするのが本来の在り方である。
*値は型(''type'')によって分類される。関数型プログラミングでは式と関数(''function'')も値そのものと見なされる。関数の終端式がそのままその関数の結果値になる。無数に存在する型同士の等価計算を円滑化する為に、型もまたメタ型(''type class'')によって分類される。
*関数は、式を引数値に適用したもの=結果値という形をとる。関数の型は、各引数値から結果値までの型の連鎖として表現される。
*関数は、ラムダ抽象のプログラミング形態である[[クロージャ]]または[[無名関数]]として式の中に組み込む事ができる。
*関数は値と同義なので、関数の引数値を関数にする事も可能であり、また関数の結果値を関数にする事も可能である。関数を引数値または結果値として扱える関数は[[高階関数]](''higher-order function'')と呼ばれる。引数値または結果値として扱われる関数は[[第一級関数]](''first-class function'')と呼ばれる。
*値は代数的データ(''algebraic data'')として表現される。代数的データは、''atom(実値)nil(不在)cons(実値+連結点)''の連鎖体であり、結果的に一つから複数以上の実値を内包する。全実値が同型の代数的データは''list''と定義される。一つの代数的データへの作用は、内包する全実値への作用と同義になる。これが関数型プログラミングの利点とされるリスト処理の自然な表現につながっている。
*[[再帰]](''recursion'')が重視されている。関数の再帰呼び出しだけでなく、データ定義の中でも同型データの再帰呼び出しがごく自然に行われる。
 
=== 設計視点 ===
=== 高階関数と第一級関数(''higher-order and first-class function'') ===
 
* 関数型プログラミングは[[宣言型プログラミング]]に属している。宣言型と対照的関係にあるのが[[命令型プログラミング]]([[手続き型プログラミング|手続き型]]や[[オブジェクト指向プログラミング|オブジェクト指向]]など)である。両者を分ける一つの基準は[[副作用 (プログラム)|副作用]](''side-effects'')に対する考え方および扱い方である。
=== 純粋関数(''pure function'') ===
関数型プログラミングは[[宣言型プログラミング]](''declarative* programming'')のカテゴリに属するパラダイムである。宣言型と対照的関係にあるのが[[命令型プログラミング]](''imperative programming'')であり、そのカテゴリには[[手続き型プログラミング]]と[[オブジェクト指向プログラミング]]などが属している。命令型と宣言型を分ける一つの基準は[[副作用 (プログラム)|副作用]](''side-effects'')に対する考え方および扱い方である。この副作用について改めて後述するが簡潔に述べると現行プロセスの閉包領域の外にある様々な情報資源の状態=いわゆる「環境」の変化と、その変化によって各プロセスの処理過程もまた影響を受ける事を指す。ここでの情報資源とは、プログラムの各種入出力(I/O)を担う[[オペレーティングシステム]]の現行状態と、プログラムを走行させている[[仮想マシン|ランタイム環境]]が提供する各種データリソースを意味する。データリソースには純粋関数型では扱いにくい動的配列と動的連想配列も含まれる。
* 命令型プログラミングは前述の「環境」に対して自由に作用を及ぼせるパラダイムであり、それが”''imperative''”の由来にもなっている。それに対して宣言型プログラミングは作用を及ぼせる対象と、自身がその影響を受ける事になる対象が、あらかじめ初期値または入力値として”''declarative''”された情報資源(=データ)のみに限られている。加えて関数型プログラミングは原則的に、宣言されたデータに対しても作用を及ぼさず、他の値を導き出す為の因子として扱う。
===* 参照透過性(''referential transparency'') ===
===* 評価戦略(''evaluation strategy'') ===
===* 純粋関数(''pure function'') ===
 
== 歴史 ==