2016年2月9日火曜日

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

前編だけ公開して、後編は眠らせたままにしていたようです。
後編の今回は、実際のコードを交えてより実践的な視点から関数型スタイルプログラミングを俯瞰してみようと思います。では、まずは以下のサンプルコードを開いてみてください。



上記のサンプルコードは、C#を使用して関数型スタイルと非関数型スタイルで0から100までの偶数を並べあげる処理を記述したものです。コメントを全て英語で記述したため、ソースコード単体だと読みにくいかもしれないですが、上から順に、forループ、foreachループ、LINQ to Objects、LINQ to SQLを使用しています。このうち、まず、本筋とあまり関係はないけど、補足が必要そうなところから解説します。
foreachループ以降のソリューションで登場する
Enumerable.Range(from, to, step=1)
メソッドは、fromからtoまでstep刻みの整数列をIEnumerableオブジェクトとして生成します。

さて、本題の関数型スタイルに入りましょう。関数型言語と聞くと、Haskellを筆頭として、C系の手続き型スタイルに慣れてしまったプログラマーにとってみると、どうしてもとっつきにくい印象を抱いてしまう人が多いことでしょう。確かに、文(値を返さない文法構造の一種)が存在せず全てを関数で処理し、関数が状態を持たないと聞くと、ついつい腰が重くなってしまいそうな気配がします。
しかし、ここでお勧めする関数型スタイルとは、C++やC#に代表されるマルチパラダイム言語においてアクセント的に使用します。そもそも、関数型言語と手続き型言語では、根本的に使用される概念も異なるため、すべてを関数型化できるわけではないですからね。

上記の例の3番目の記述法を見てみましょう。この一文、日本語として読み解くと、「even_numbers_lto(0から100までの偶数)は0から100までの整数のうち、2で割り切れる数」と解釈できます。4番目の記述法は、これをよりSQLライクに記述していると考えられます。つまり、この2文における=は、数学におけるものと同じように、等価や宣言を意味しているとも解釈できます。

前編にも記載したように手続き型言語では、プログラマの役目はコンピュータにある問題の処理方法(How -- instructions)を教えることでした。
一方、関数型言語では、Howを表すブロックが既に存在するため、これを組み合わせて(What, When)を記述することに集中することができます。この特徴から、特にビッグデータに代表されるような大量のデータを扱う場合や、手順よりも値が変化した時やユーザインタアクションがあった時にラベルの内容を変えるなど、GUIの処理を定義する際などに便利と考えられます。さらに、関数型言語の関数の特徴として副作用を持たないというものがありますが、手続き型に書くよりも宣言的に記述が行えるため、コールバックベースのGUI処理を行うよりも見通しが立ちやすいという利点もあります。

2016/2/9 23:21追記:
この意味では、リアクティブプログラミング(いい記事がなかったので、リンク先は英語版のWikipediaです)というパラダイムが考案されています。

0 件のコメント:

コメントを投稿

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