人気ブログランキング | 話題のタグを見る

Ruby で関数型プログラムをするとうれしい理由

Scheme の文法は驚くほど単純だ。

これは、何を意味しているかというと、関数型言語の特徴はその構文規則にあるのではなく、プログラムを全て関数で記述するというプログラミングスタイルにあるのだということだ。

したがって、Rubyでもプログラムを関数で組み立てていけば、関数型プログラム言語もどきのことが十分できる。しかし、手続き型言語のRubyでどうしてわざわざ関数型のプログラムをする必要があるのだろうか。関数型のプログラムをすることで何かいいことがあるのだろうか。

そのメリットのひとつは、部品のテストが非常に楽だということだ。

管理人の場合、Rubyを使ってRoRのような大規模なプログラムを組むことは不可能だ。むしろ、日常のちょっとしたアイディアを試したりするのに、小さなブログラムを作って楽しんでいる。そういうお気軽な使い方で一番面倒なのはデバッグだ。Rubyは仕様が使いやすいように設計されているし、インタープリタなのでコンパイルもいらない。それでも、デバッグの作業は結構面倒に感じる。

ところが、関数型プログラムのスタイルでプログラムを作ると、個々の部品が関数なので、作ったそばからすぐテストすることができる。irb で対話的にいじっているうちにプログラムが完成してしまうのだ。たとえば、二次方程式のプログラムを関数を使って作成してみよう。

解を求める方程式は aX^2 + bx + c = 0 の形をしているとする。

まずは判別式を求める関数 d(a, b, c) をつくる。

def d(a, b, c)
b*b - 4*a*c
end

d(a, b, c) の引数に値を与えてテストしてみると次のようになる。

d(1, 2, 1)
=> 0

つぎに2個の根のうち大きいほうを計算する関数 x1(b, d) を作る。引数 d には判別式の値を入れることにする。

def x1(a, b, d)
(- b + Math.sqrt(d)) / 2 / a
end

テストしてみる。

x1(1, 2, d(1, 2, -3))
=> 1.0

X1がうまくいったので小さいほうの根の x2 もプログラムする。

def x2(a, b, d)
(- b - Math.sqrt(d)) / 2 / a
end

二次方程式の根を計算する root2 は上の x1 と x2 を返すだけだ。

def root2(a, b, c)
return x1(a, b, d(a, b, c)), x2(a, b, d(a, b, c))
end

テストしてみよう

root2(1, 2, -3)
=> [1.0, -3.0]

うまくいったようだ。さらに、a が 0 の場合も考えると最終的なプログラムは次のようになる。

def root(a, b, c)
  if a == 0
    - c / b
  else
    root2(a, b, c)
  end
end

irb で対話的に操作しているうちに、テストとデバッグが同時進行でできてしまった。小さな関数のプログラムは頭の負担が少ないし、作ったらすぐに部品のテストをすることができる。Ruby で関数型のプログラムをすることで、お気楽にプログラム開発を楽しめる場合があるのだ。
by tnomura9 | 2008-01-31 08:14 | Ruby | Comments(0)
<< Rubyと関数プログラミング 再帰 >>