「関数型プログラミング」の版間の差分
削除された内容 追加された内容
SML 言語族に関する説明を少し強化 |
不適切、あるいは冗長な記述を削除。大部分の記述を修正。ScalaはOOPとFPの両方を売りにした言語で、関数型プログラミング言語に分類しても差し支えない。 |
||
1行目:
{{独自研究|date=2014年4月}}
{{プログラミング言語|index=かんすうかたけんこ}}
'''関数型言語'''(かんすうがたげんご、functional language)は、'''関数型プログラミング'''に向いた特徴を持つ[[プログラミング言語]]、関数型プログラミング言語(functional programming language)の略称である
== 関数型プログラミング ==
関数型プログラミングは、理論的な計算モデルとして[[ラムダ計算]]や[[項書き換え]]を基礎とする。そのため、関数は[[第一級オブジェクト]]として扱えることが必要となる。
関数への引数がプログラムへの入力で、関数を引数に作用させて評価して得られる値がプログラムからの出力であるとすると、コンピュータプログラムはある種の関数であると考えることができる。ここで、入力や出力は記憶装置中のファイルのようなものばかりではなく、マウスの動きの情報といった入力や、画面への表示といった出力も考えられ、関数型プログラミングにおいては実際にそれらを扱う関数としてモデル化する。
他の[[プログラミングパラダイム]]との関連としては、関数型プログラミングは[[論理プログラミング|論理型プログラミング]]と同じく[[宣言型プログラミング]]・[[非手続き型言語|非手続き型プログラミング]]で、[[手続き型プログラミング]]・[[命令型プログラミング]]と分類を異にする。
== 概要 ==
関数型プログラミング言語
純粋関数型プログラミング言語では、[[参照透過性]]が常に保たれるという意味において、全ての[[式 (プログラミング)|式]]や関数
非純粋関数型言語では、参照透過性を壊す、副作用があるような式や関数も存在する。Lispなどでデータ構造の破壊的変更などの副作用を多用したプログラミングを
[[JavaScript]]や[[Java]]など近年の[[高水準言語]]には、関数型言語の機能や特徴を取り入れているものがある。変数の値やオブジェクトの状態を書き換えるプログラミングスタイルを通常とするため、関数型言語とは
▲純粋関数型プログラミング言語では、[[参照透過性]]が常に保たれるという意味において、全ての[[式 (プログラミング)|式]]や関数は[[副作用 (プログラム)|副作用]]を持たない。入出力などのために、多くの純粋関数型プログラミング言語は正格性に関して非正格であり、引数はデフォルトで[[遅延評価]]である。また入出力などを[[参照透過性]]を保ったまま実現するために、たとえば[[Haskell]]では[[モナド (プログラミング)|モナド]]、[[Clean]]では{{仮リンク|一意型|en|Uniqueness type}}という特殊な型を通してでのみ入出力などを扱えるようにしている。
なお、「関数型言語である」と「関数型プログラミングをする」は同値ではなく、関数型には分類されない言語で関数型プログラミングをすることや、関数型プログラミングを基本とする言語の上で他のパラダイムを実現する例もある<ref name="Novatchev">{{cite web | url = http://arxiv.org/abs/cs/0509027 | author = Oleg Kiselyov, Ralf Lämmel | title = Haskell's overlooked object system | accessdate = Sep 10, 2005}}</ref>。
▲非純粋関数型言語では、参照透過性を壊す、副作用があるような式や関数も存在する。Lispなどでデータ構造の破壊的変更などの副作用を多用したプログラミングをおこなうと、それはもはや手続き型プログラミングと同じである。非純粋関数型言語は多くが正格性に関して正格であり、[[評価戦略]]としては正格評価(先行評価)である。無限リストのような技巧を使うために、明示して遅延評価をおこなわせるための機構を持つ。
[[データフロープログラミング]]言語も関数型言語と共通した特徴を部分的に持つ。
▲[[JavaScript]]など近年の[[高水準言語]]には、関数型言語の機能や特徴を取り入れているものがある。変数の値やオブジェクトの状態を書き換えるプログラミングスタイルを通常とするため、関数型言語とはしない。一方[[LISP]]は、その多くが副作用のある式や関数が多数あり、手続き型スタイルでのプログラミングも可能だが、理論的なモデル(「[[純LISP]]」)の存在や副作用を使わないプログラミングが基本であること、歴史的理由などから、関数型プログラミング言語に含む。
== 歴史 ==
[[LISP]]は、その基本機能のモデルとして関数型の[[純LISP]]を持つなどといった特徴がある、最初の関数型言語である。今日広く使われているLisp方言のうち特に[[Scheme]]は関数型としての特徴が強い。
現代的な関数型プログラミング言語の祖としてはアイディアが1966年に発表された[[ISWIM]]が挙げられるが、1970年前後までは関数型プログラミング言語の歴史はLispの発展が主である。1970年代にプロジェクトが開始された[[w:Logic for Computable Functions]]のための言語として[[ML (プログラミング言語)|ML]]が作られている。
32 ⟶ 31行目:
またLISPにおいて、変数のスコープに静的スコープを採用した[[Scheme]]が誕生したのが1975年である。
1977年、FORTRANの設計と[[バッカス・ナウア記法|BNF]]の発明の業績でこの年の[[チューリング賞]]を受賞した[[ジョン・バッカス]]は、''Can Programming Be Liberated From the von Neumann Style?: A Functional Style and Its Algebra of Programs''<ref>「プログラミングはフォン・ノイマン・スタイルから解放されうるか?: 関数型プログラミング・スタイルとそのプログラム代数」、[[米澤明憲]]訳『ACMチューリング賞講演集』([[共立出版]])pp. 83-156</ref>と題した受賞記念講演で関数型プログラミングの重要性を訴えた。講演では[[w:FP (programming language)|FP]]という関数型プログラミング言語の紹介もした(サブタイトルの後半の「プログラムの代数」はこれを指す)が、これは[[APL]](特に、[[高階関数]]の意味がある記号(APLの用語ではoperator([[作用素]])という))の影響を受けている
バッカスのFPは広く使用されることはなかったが、この後関数型プログラミング言語の研究・開発は広まることとなった。1985年に[[Miranda]]が登場した。1987年に、遅延評価の純粋関数型プログラミング言語の標準の必要性が認識され[[Haskell]]の策定が始まった。1990年にHaskell 1.0仕様がリリースされた。同じく1990年にはMLの標準である[[Standard ML]]もリリースされている。
[[Clean]]は1987年に登場したが、発展の過程で[[Haskell]]の影響を受けている。1996年に、ML処理系のひとつであったCamlに[[オブジェクト指向]]を追加した[[OCaml]]が登場した。また日本ではSMLに独自の拡張を
21世紀に入ると、[[Java仮想マシン]]や[[共通言語基盤|CLI]]
== 代表的な関数型言語 ==
=== 純粋
* 強い静的型付け
** [[Clean]]
** [[Haskell]]
** [[Miranda]]
** [[Idris]]
* 型なし
** [[Lazy K]]
=== 非純粋
* 強い静的型付け
** [[プログラミング言語ML|ML]]
55行目:
** [[OCaml]]
** [[F Sharp|F#]]
** [[Scala]]
* 動的型付け
** [[Erlang]]
|