櫻庭さん(@skrb)にJavaによる関数型プログラミング ―Java 8ラムダ式とStreamを頂いたので感想を書きます。
この本は、Java8の新機能を学びたい!というよりも、関数型の考え方を学びたいという人向けな気がしました。
2章、3章はラムダ・Stream APIの使い方を紹介していますが、この本の醍醐味は4章以降でしょう。 プログラミングにおける考え方の幅を広げたい人は読んでみると良いと思います。(ただ、ギョウムアプリケーションでは実践しない方が良いような気がしますw)
「プログラミングClojure」とか呼んだことがあると、あーこれClojureでやったわーって感覚になる箇所があちこちにあると思います。無限の遅延ストリームとか末尾再帰最適化とか。(そしてマクロがほしくなる・・・特に5章あたり、それwith-open-file
やーってなる)
時間ができたら、7章の例を参考に相互再帰最適化を実装してみたい。
ところで、↓のプログラムを実行するとどういう出力になるでしょうか。
List<String> langs = Arrays.asList("C++", "Go", "Java", "Python", "Ruby");
String a = langs.stream()
.map(lang -> {
System.out.println("toUppercase(" + lang + ")");
return lang.toUpperCase();
})
.filter(lang -> {
System.out.println("length(" + lang + ")");
return lang.length() == 4;
})
.findFirst()
.get();
わざわざここで上げている訳だから、
toUppercase(C++)
toUppercase(Go)
toUppercase(Java)
toUppercase(Python)
toUppercase(Ruby)
length(C++)
length(GO)
length(JAVA)
length(PYTHON)
length(RUBY)
にはならないです。
いかのどれかです。実行してみてください。
(A)
length(C++)
length(Go)
length(Java)
toUppercase(Java)
(B)
toUppercase(C++)
length(C++)
toUppercase(Go)
length(GO)
toUppercase(Java)
length(JAVA)
(C)
toUppercase(C++)
toUppercase(Go)
toUppercase(Java)
length(C++)
length(Go)
length(JAVA)
なんでこうなるか気になる方は是非本書を読んでほしいです(コード例は変えています)。 そして、なんで関数型では副作用のあるコードが好ましくないかが理解できると思います。