[Elixir]関数型言語に触れてみる
普段何か簡単な処理をする時にはRubyを常用してきた。
ただそればかりじゃなく、他にも何か別の言語を使えるようになりたいなぁと思い、
数年前にLISPやScalaをインストールしてみたんだけど、
なかなか常用するぐらいには各言語の特徴を理解できず途中で放り投げていた。
そんな中、最近関数型言語に関する記事を多々見かけるようになり、
もう一度何か別の言語に手を出してみようかなと徘徊していた所、下記の記事に出会った。
[CodeIQ]「Ruby風味のプログラミング言語」四天王現る!
記事の中で関数型言語としてElixirという言語が紹介されており、
Ruby風味でちょっと面白そうなので早速インストールしてみる事にした。
試しに何か書いてみる
お題として「500から10000まで1.03倍し続けた数字を表示する」というプログラムを考えてみる。
まずはRubyから
なんかもっと良い書き方があるような気がするが、とりあえずwhileで回した。
次にElixir。
関数型言語の場合、繰り返しは再帰を用いて表現するのが好まれるようで、
見よう見まねで以下のプログラムを書いた。
求める結果は得られたが、再帰を使い慣れていない為か、書くのに時間がかかってしまった。
さらに言うなら結構行数が多くてどうもしっくり来ない。
もっとお手軽に表現できないもんかとElixir関連の記事を漁っていた所、
下記の無限リストが使えそうだと思い参考にしてみた。
上の記事を参考にして書き直したのが以下。
短くはなったが、ここで問題が発生。実行すると以下のエラーが出てしまった。
どうも10000までのリストは得られているようだが、8行目の処理でエラーが出ているという表示だ。
Stream.filterではなくEnum.takeで個数を指定するとエラーが出なくなる。
filterを使って条件でリストを取得しようとするとエラーが出る。filter/2ではダメなんだろうか。
参考にした無限リストのサンプルは、Enum.take(10)などでリストから何個取得するか明示している。
が、今回のお題だと条件にマッチするリストが元から何個あるのかわからないのでtake/2は使えない。
他にもStreamを使っているサンプルを探してみたが、
take/2で何個取得するのが明示してあるものが多くエラー解消に結びつかない。
英語だからと避けていた公式ドキュメントで、改めて使えそうなものがないか物色。
[Elixir公式]take_while(collection, fun) … 名前がそれっぽいので説明を見る。
Takes the items from the beginning of collection while fun returns a truthy value.
これじゃね?
ということで9行目Stream.filterの部分を書き換える。
教訓: 公式ドキュメントを見るのは大切ですね
今回Ruby以外の言語も使えるようになりたいという事でElixirを触ってみましたが、
パイプライン演算子やStream(遅延評価)など面白い要素があり勉強になりました。
これからも、もう少し色々試してみようと思います。