2014年3月30日日曜日

関数型プログラミングスタイルのすゝめ(前編)

え〜、半年以上ご無沙汰していたみたいですね。どうもはざまです。
今回はまた技術系ブログらしく、技術系の啓蒙文でも書いてみようかと思います。

さて、今回のテーマは「関数型プログラミングスタイル」なんですが、一体それはなんぞやという話ですよね?この名前自体は思いつきでつけただけなので、特に気にする必要はないのですが、では一体関数型プログラミングとはなんなのかという話をする前に、まず「関数」の話から始めましょう。
数学における「関数」は本来「函数」と漢字表記していました。これについて関数は、「入力を変化させる箱だ」というような解説を学生の頃に受けた記憶があるのですが、我らがWikipedia先生によると、この表記とこの説明にはなんの関連性もないらしいです・・・
さて、おぼろげになりつつある記憶をたどってみれば、この言葉を初めて聞いたのは中学校の数学の時間ではないでしょうか?その頃に出てきた関数といったら例えば、f(x) = x^2などでしょうか。この等式は、x=1,-1を代入するとf(1) = f(-1) = 1、x=2, -2を代入するとf(2) = f(-2) = 4・・・というように代入されるxによって出力となる値(この場合はf(x))が変化しました。
一般に、ある入力x,y,z...に対して一意な出力f(x,y,z...)を返す写像(平たく言えば入力に対して処理を施して出力を返す変換器)のことを関数と呼んでいます。数学の世界では入力も出力も実数になるものを実関数、両方共複素数となるものを複素関数などと呼びます。

では、プログラムにおける関数はどうでしょうか?プログラムにおける入力・出力は、なにも数値とは限りません。数値や文字列、それらを複数含むデータなど、ありとあらゆるデータが入力・出力になりえます。また、プログラムにおける関数の中には、今ではめったにこの名前を使う言語はないのですが、Pascalなどの古い言語では「プロシージャ」または「手続き」と呼ばれることもあり、これは特に出力(プログラミングではこれを戻り値または返り値と呼ぶ)を返さない関数のことを指します。このプロシージャは変換器というよりも処理の羅列という側面が強く、「関数」と呼ばない言語が存在するのもうなずけるところでしょう。

 ざっと関数の意味と歴史について触れたところで、関数型プログラミングの話に移ることにしましょう。現在、世の中で広く使われているプログラミング言語のおよそ99%(数字自体は適当ですが(^^;; )はC言語を先祖とする手続き型言語、またはオブジェクト指向言語と呼ばれるものです。
「名は体を表す」とはよく言ったもので、手続き型言語は主に手続きの羅列で実行する処理を表します。言ってみれば手続き型言語は、赤子に歩き方を手取り足取り教えるように、コンピュータにある問題を解決するための手順をひとつひとつ教えることで、プログラムを記述します。
オブジェクト指向言語は、これの単純な拡張に過ぎず、あるデータがあったらそれに対して施すべき処理(手続き)はそのデータに紐づくものなのだから、ひとまとめにして考えるようにすればわかりやすいよねという思想に基づき生まれたものでしかありません。このような構造をこれらの言語では、「クラス」と呼びますが、この記事の本題とは関係無いため、割愛します。
手続き型言語は部品も含めて自分で一からつくり上げるという印象が強い一方で、今回の本題に関連する関数型言語はどちらかと言えば、ブロックを積み重ねて問題解決の手順を示します。したがって、関数型言語の問題解決手順は、自由度が幾分低い代わりにその機能が類推しやすく、把握しやすいといえます。
もちろん、何にでも例外はつきものなので、手続き型・オブジェクト指向言語でもいろんなブロックがあらかじめ用意されている言語や、一般に関数型言語と言われていても、手続き型言語的側面を持つものもあります。


後編ではC#によるサンプルコードを交えつつ、実践的な関数型プログラミングスタイルの解説をしていきます。

0 件のコメント:

コメントを投稿

なにか意見や感想、質問などがあれば、ご自由にお書きください。