純粋関数型言語って何?
引数が同じであれば、結果もまた同じになるという意味での「関数」を第一級オブジェクトとしたプログラミング言語のことです。
例えばオブジェクト指向プログラミング(C#)であれば、
class Hoge{
private int fuga;
public Hoge(int a){
fuga = a;
}
public int Add(int b){
fuga = fuga + b;
return b;
}
}
このような実装がよく見られますね。
しかし、この実装はインスタンスを生成した後、Add関数を呼ぶ度にローカル変数fugaの値が変わっていき、Add関数が返す値が変わってしまいます。このようなことを純粋関数型言語では許していません。
では、どのように純粋関数型言語(Haskell)で書くかというと、こうなります。
add :: Int -> Int -> Int
add a b = a + b
まぁ、この関数自体は、C#などの所謂オブジェクト指向プログラミング言語でも表現できるわけなのですが、味噌になるのは、こういった書き方を”強制”する、ということなのです。
純粋関数型プログラミング言語は、このHaskellのように構文が他の言語と大きく違うものが多く、とっつきにくいため、JavaやC#といった現在最もよく使われているC言語由来のオブジェクト指向プログラミング言語からは移行しにくいと思います。
では、この純粋関数型言語がなぜ、もてはやされているのか?
そういう疑問を持つのは必然だと思います。
何故、関数型プログラミング言語が良いのか?
これに関して、私は2点挙げられると思います。
- テストコードが書きやすいこと
- 数学の公理系というバグの(多分)1ない世界に持ち込めること
この2点です。
1に関しては、上記2つのコードを見ると分かっていただけると思うのですが、
C#のコードは、テストを1回する毎にインスタンスを作り直さなければならないことが分かるかと思います。(勿論、そうじゃない書き方があることは分かっています。しかし、DBやファイルなどのデータやハードウェアを扱う際には、このようなコードが往々にして現れるのをご存じなはずです。)
2に関してはどういうことか?
以下に説明します。
公理系ってなんだ?
公理系とは数学において、数学を論ずるに際して、最も基本的な仮定のことです。
もう少し正確に表すと、その学問を考えるのに必要な前提条件の集まりです。
ユークリッド幾何学で言えば、
「平面上で直線外の1点を通って、この直線と交わらない直線がただ1本存在する。」(ユークリッド原論:第5公準の別解釈)
といったものがこれにあたります。
小中高と私達はこのユークリッド幾何学に基づいた幾何学(図形の勉強)を習っていたわけです。2
わかりづらければ、中高の物理でよく書かれていた”なお摩擦は考えないものとする”的なものだと思ってくれると良いと思います。
プログラミングの世界に適用するならば、
"long型で表現できる整数より大きな数は存在しないものとする。"
"丸め誤差は考えないものとする"
などが当たりますかね(笑)3
純粋型関数言語に適用される数学の世界:圏論
では、どのような数学の公理系が純粋型関数型関数言語に適用されているのかというと、初めからちょこちょこと出てきている”圏論”という数学の論理の公理系です。これは関数型言語が生まれた頃から意識されて作られたのか、それとも数学の論理に似ていたからそちらに寄せていっているのかはわかりませんが4、新しい"純粋"関数型言語においては、確実に"圏論"を意識されていることと思います。
この記事を見て下さった方は是非、一緒に圏論と関数型プログラミングの世界へ旅をするのに付き合ってくださると幸いです。
これからのロードマップ
- [Haskell]純粋関数型言語と圏論:序論 ← この記事
- 【予定】[Haskell]純粋関数型言語と圏論:集合の写像
参考文献
- Steve Awodey -訳: 前原和寿- 2015/09/25 - 圏論 原著第2版 - 共立出版
- Bryan O'Sullivan・John Goerzen・Don Stewart - 訳: 山下信夫・伊藤勝利 - 2009/10/26 - Real World Haskell ー実戦で学ぶ関数型言語プログラミング