「関数型プログラミング」の版間の差分
削除された内容 追加された内容
編集の要約なし |
編集の要約なし |
||
(同じ利用者による、間の1版が非表示) | |||
6行目:
'''関数型言語'''({{lang-en-short|''functional language''}})は、'''関数型プログラミング'''のスタイルまたは[[プログラミングパラダイム|パラダイム]]を扱う[[プログラミング言語]]の総称である。関数型プログラミングは関数の[[写像|適用]]と[[関数の合成|合成]]から組み立てられる[[宣言型プログラミング]]の一種であり、関数は[[引数]]の適用から先行式の[[評価戦略|評価]]を後続式の適用に繋げて終端評価に到る[[式 (プログラミング)|式]]の[[ツリー構造|ツリー]]として定義される。関数は引数ないし返値として渡せる[[第一級関数]]として扱われる。
関数型プログラミングは[[数理論理学]]と代数系をルーツにし、[[ラムダ計算]]と[[コンビネータ論理]]を幹にして構築され、[[LISP]]言語が実装面の先駆になっている。応用面では[[圏論]]がパラダイムモデルにされている。関数の数学的な純粋性を指向したものは純粋関数型言語と個別に定義されている。[[命令型プログラミング]]言語では単に有用な構文スタイルとして扱われている事が多い。[[高階関数]]、[[第一級関数]]、{{仮リンク|関数合成|en|Function composition (computer science)|label=}}、{{仮リンク|部分適用|en|Partial application|label=}}、[[無名関数]]、[[クロージャ]]、[[継続]]、[[ボトム型|部分関数]]、{{仮リンク|ポイントフリー|en|Tacit programming|label=}}、[[パイプライン処理|パイプライン]]、[[イテレータ]]、[[ジェネレータ (プログラミング)|ジェネレータ]]、[[代数的データ型]]、[[型推論]]、[[パターンマッチング]]、[[ガード (プログラミング)|ガード]]、{{仮リンク|パラメトリック多相|en|Parametric polymorphism|label=}}、{{仮リンク|アドホック多相|en|Ad hoc polymorphism|label=}}
== 特徴 ==
26行目:
*仮引数記述を省略した関数はポイントフリーと呼ばれ、その省略箇所に先行式評価値が実引数として暗黙適用される。実引数記述を省略して先行式評価値を後続関数の仮引数箇所に暗黙適用するのもポイントフリーと呼ばれる。この暗黙適用の式を並べて連鎖させる手法は[[パイプライン処理|パイプライン]]と呼ばれる。言語によっては特別な演算子と併せて明示する。
*関数は名前付きと名前無しの二通りある。後者はラムダ抽象を模した構文で式中に直接定義される。これは[[無名関数]]と呼ばれる。式内に自由変数を持った無名関数は[[クロージャ]]と個別に定義される。自由変数には外部データが代入される。自身を参照する無名関数を内包したデータ構造体(=[[関数オブジェクト]])もクロージャに相当する。
*[[無名関数]]は引数をピュア[[写像|マッピング]]する純粋関数であるが、毎回違う値が渡される用途から事実上[[メモ化]]できない事がコーディング上の利便性を除いた存在理由になっている。[[クロージャ]]の引数[[写像|マッピング]]は式内の自由変数に影響され、またその自由変数に作用する事もある
*関数の名前は、それに結び付けられた式または式ツリーの[[不動点]]の表現になる。自式の不動点を式内に置いて新たな引数と共に[[高階論理]]の式として評価する手法は[[再帰]]と呼ばれる。
*イミュータブル性が重視されない場合、関数の終端式での再帰は、実引数の更新+先端式へのアドレスジャンプと同等に見なせるので専らそちらに最適化される。これは[[末尾再帰]]と呼ばれる。同様の仕組みで相互再帰を
*リスト処理時にリストの各要素に対する作用子として渡される第一級関数は[[反復子|イテレータ]]と呼ばれる。作用後の各要素を別の新生リストに向けて複製する働きを加えたものは[[ジェネレータ (プログラミング)|ジェネレータ]]と呼ばれる。これは[[イミュータブル]]重視時に多用される。前者はポイントフリーの無名関数、後者はポイントフリーのクロージャとして定義される事が多い。
*任意のタイミングで遅延評価(''call/cc'')される用途の第一級関数は特別に[[継続]]と呼ばれる。関数の引数を順々に評価して間に分岐などを挟める[[継続渡しスタイル]]はその応用例である。
*部分関数は引数によって[[ボトム型]]
*演算子はデフォルトの式内容を持ち、引数が1~2個に限定された関数と同義である。部分適用された演算子はセクションと呼ばれる第一級関数になる。演算子は任意の型にフックさせた再定義および追加定義ができる。これはアドホック多相と呼ばれる。
41行目:
*代数的データ型は、代数的データ型の入れ子で帰納的に構成される事もあるがその末端は必ずプロパー型になる。この帰納的な仕組みは[[高階論理|高階]]型(''higher-order types'')と呼ばれる。
*代数的データ型は、プロパー型に到るまでの帰納パターンである[[カインド (型理論)|カインド]]で抽象化分類される。カインドは「*→*」「*」のように表現される。カインドはパターンマッチングと型シノニムの成立基準になる。
*左辺のもので右辺のものを置き換えられるという代数的データ型間の
*代数的データ型は、[[直積集合|直積型]](''product type'')[[非交和|非交和型]](''sum type'')帰納型(''inductive type'')[[依存型]](''dependent type'')ユニット型(''unit type'')などのタイプを持つ。式的役割は直積型=×演算子、非交和型=+演算子、帰納型=式再帰または高階式、依存型=パターンマッチング式、ユニット型=NILである。この5タイプで大半の値を表現できる。
*直積型は、(A, B) のような[[タプル]]
*非交和型は、(A | B) のような[[共用体|修飾共用体]]または[[列挙型]]のパターンを表わす。前者は型推論による等価性で、後者は評価による等値性で識別される非交和である。前者はユニオン型(''union type'')と個別定義されてもいる。
*帰納型は、[[ボックス化]]と前述の入れ子のパターンを表わす。また帰納型と非交和型とユニット型は併用されて[[連結リスト]]、[[二分木]]、[[ツリー構造|データツリー]]のパターンを表わす。
*依存型は、一つの依存値による[[パターンマッチング]]式をそのままタイプと見なしたものである。その[[パターンマッチング|ケース節]]パターンのみはオプション型(''option type'')[[ガード (プログラミング)|ガード節]]パターンのみはリファイン型(''refinement type'')と個別定義される。これらは[[動的配列]]、Maybe値、リスト内包表記などの構造を表わす。
54行目:
=== 評価戦略 ===
関数型プログラミングにおける[[評価戦略]]とは「式存在」を「値存在」にする評価タイミングの定義を指す。これはまず正格評価(''strict evaluation'')と非正格評価(''non-strict evaluation'')の二つに大別される。
後者の非正格評価はほとんどのケースで[[遅延評価]]と同義の言葉になる。遅延評価の式存在は、関数に適用されても式存在のままであり、または変数に束縛されても式存在のままである。後続式において改めて他の関数ないし演算子に適用される時に初めて評価されて値存在になり、または改めて他の変数に束縛される時に初めて評価されて値存在になる。これが遅延評価のデフォルトタイミングである
プログラム実装上において先行評価は決して必須ではないが遅延評価の方は必須になる。[[帰納]]、[[再帰]]、[[無限]]、[[極限]]といった代数的表現は遅延評価でのみ実装できる。部分関数も遅延評価前提の式存在である。フロー分岐によって参照されなくなる式評価を結果的にスキップできる事は処理の高速化につながる。それはしばしばテクニックとしても用いられる。また[[ボトム型]]が発生する式評価のスキップは[[フォールトトレラント設計|フォールトトレランス]]にもつながる。ただし柔軟な評価タイミングは同時に式存在と値存在の
=== 参照透過性 ===
[[参照透過性]]とは関数は同じ引数値に対して必ず同じ評価値を恒久的に導出し、その評価過程において現行計算枠外の情報資源に一切の作用を及ぼさないというプロセス上の枠組みを意味する。現行計算枠外のいずれかの情報資源が変化するのと同時にいずれかの関数の評価過程も変化してしまう現象は[[副作用 (プログラム)|副作用]]と呼ばれる。参照透過性はこの副作用の排除も同時に意味している。参照透過性
=== 型システム ===
|