Saturday, December 26, 2015

関数型言語 三種の神器

関数型言語のパラダイムの恩恵の代表格として、以下のメソッドがある

map
filter
reduce (fold)

オブジェクトがクラスベースでものを考えるのと違い、関数型はcollectionベースでものを考える。

map

mapはcollectionの写像を作る。

例えば

map(lambda x: x*2,  [1,2,3,4,5])

だったら これは

[2,4,6,8,10]

を返す。これを手続き型(php?)で同じ処理やると

$y = array();
foreach(array(1,2,3,4,5) as $x ) {
     $y[] = $x*2;
}

とかなる。

これだけみても関数型がどれだけエコかっていうのはおわかりいただけるであろう。

filter

filterは特定の条件のelementのみを、collectionから抽出して同じくcollectionを返す

例えば

filter(lambda x: x % 2 == 0, [1,2,3,4,5])



$y = [];
foreach(array(1,2,3,4,5) as $x) {
    if($x % 2 == 0){
        $y[] = $x;
    }
}

は同じことをやっている。つまり特定の条件(ここだと偶数)の要素だけをcollectionとして返している


reduce (fold)

pythonでは reduceという呼び方だが、一般にはfoldと呼ばれることが多い(HaskellはfoldlだしScalaではfoldLeftとか)。まあコンセプトとして、一つのcollection(集合)を「折り畳む」とか「減らす、集約する」ということだ。

例えばphpなんかで、

$sum = 0;
$l = array(1,2,3,4,5);
 for($i=0; $i < count($l); $i++ ){
      $sum += $l[$i];
}

これで目的は 一つのcollectionの中身をいっこいっこ出して行って累積させていくのだ、が、これをreduce(fold)でやると

reduce(lambda x, y: x+y , [1,2,3,4,5])

つまり一行で終了。

全体的にみていても関数型の方がメンテナンスもしやすいし、コードの把握もしやすい(5000ページの書類と10ページの書類、どっちが読みやすいかってこと)し、「壊れにくい」


関数型が数学的だというのは、まず関数が第一市民であること(first class citizen)、 また、数学は、公式じたいスタティック(静的)で、

sin(θ) とかだったら、

sinっていう公式じたいの中身や状態が変化することはありえなくて、絶対そこは固定していて、パラメータ(input)と 返り値(output)だけが変化しうる状態、

これが関数型プログラミングが数学であり、 アカデミックであるゆえんなのだ。

 クラスという概念は、大量のコードを分類(分類はアリストテレスの時代から学問の基本)してわかりやすくしようという試みだったけど、結局弊害はあって、所詮データのあつまりだし、

「集合 」と「数式」で考えよう、

これが関数型。

よって三種の神器。

よって関数型を使えない言語はウンコ。

また、僕は(scalaなんかもサポートはしてるけど)シングルトンって考えも嫌いで、CPU二個になった今そんな考えで設計してること自体ありえないし、使うならせめて悪いことをしている罪の意識くらいは持ってほしい

ってくらい僕は極論を持っている。組み込み系の畑の人とかだとまた違った意見なんだろうけど、アプリケーションエンジニアとして状態に依存するコーディングなんてありえない。

食べかけのご飯を 部屋の隅に二ヶ月放置している家に虫(バグ)がたからないわけがない。

オブジェクト指向、手続き型を不特定多数で維持するっていうことはこれくらい罪深い。(アーメン)

デスマーチなんてほぼこれが原因であることが多い

以上。

No comments:

Post a Comment