Haskell 関数プログラミングがブレイクする予感


Haskellというプログラミング言語をご存知でしょうか?
関数プログラミングという考え方を元に開発された言語で最近ユーザーが増えてきているようです。

関数プログラミングに関してはなぜ関数プログラミングは重要かが参考になります。(ちょっと難しいですが。)

関数プログラミングの特徴としてはこんな感じです。

1 副作用がない
 ソフトウェアのバグで多いのがこの副作用です。
例えば次のようなコードは手続き型言語でよく見られます。

x = x +1

Destructive Updateと呼ばれるもので値が書き換えられるためプログラムに影響を与えてしまいます。
似たような事例で関数の中で他から参照されている変数を書き換えてしまうというのもバグのもとです。
関数プログラミングではこのような関数の副作用を許しません。
変数に値が設定されたら変更も許可しません。

2 遅延評価
 遅延評価とは必要な時に必要なものだけしか評価しないという機能です。
こういうと何のことがわからないと思いますので例をひとつ。

例えばJavaやCなどでこんなコードを書くとします。

List makeList()
{
   List current = new List();
   current.value = 1;
   current.next = makeList();
   return current;
}

これはリスト構造のデータを作成するコードですが、関数内で自分自身を呼んでいる再帰呼び出しになっています。
この関数を呼ぶと無限ループに陥ってしまいます。

これをHaskellで書くとこんな感じになります。

makeList = 1: makeList

短いですね〓。
この中で : (コロン)はリスト項目をつなぐという意味です。
つまりこの式の意味は1とmakeList関数が出力するリストをつなげるという意味になります。
これも再帰呼び出しの形になっているのでこのまま呼ぶと同じように無限ループになってしまいます。
しかし他の関数と一緒に呼ぶと遅延評価が効いてきます。

head makeList
=> 1

headはリストの最初だけを返すという関数です。
headと一緒にmakeListを呼ぶと最初のリストだけ返してmakeListは終了します。
こんな芸当は手続き型言語ではできないですよね。

3 モジュール化

 2の例にあったように関数をモジュールと考えてそれをつなぐ感じでコーディングができます。
なおかつ関数同士の依存性が少ないため大規模なソフトウェアを開発しやすくなっています。
先ほどの無限ループの例だとJavaとかCのプログラムだとひとつの関数の不具合でプログラムが動かなくなってしまいますからね。


Haskellの特徴としてはコードが短く書けるとかインタープリターとコンパイラがあるなどの特徴があります。
関数プログラミングの欠点はI/Oが多いプログラムやDBアクセス系プログラムには向いていないようです。

RubyHaskellを組み合わせて開発するといいかもしれませんね。