Thursday, February 2, 2012

Python/Ruby, Java, Erlangの違いと、ファンクションプログラミング

Dynamic Typingで、関数がオブジェクトとして扱われるErlangは、PythonやRubyに似ているところもあります。一方でJavaはStatic Typingで、関数はオブジェクトとして扱われないので、そこは仲間外れと言えます。

同じく関数がオブジェクトとして扱われるといっても、Python/RubyのファンクションプログラミングとErlangのファンクションプログラミングでは色々大きな違いがあるのですが、今日はPython/Ruby, Erlangがサポートしていて、Javaがサポートしていないファンクションプログラミングの1つ、"Higher order functions"について見ていこうと思います。



[1, 9, 3, 5, 8, 4, 2]というリストがあったとして、ここから3以上のものを取り除きたいとしたら、Javaであればこんな感じで書くことが多いと思います。




さらに一般化してやりたいなぁという場合は、次のようなこともできるでしょう。かなり長くなってしまいますが、「必要なもの以外取り除く」という汎用的なfilter関数を定義し、「何が必要で何が必要ではないか」を決めるためのPredicateインターフェースを定義し、最後に、使う際に適切なPredicateの実装クラスを渡しています。まぁ、Comparatorの考え方と一緒ですね。



一番初めのコードではlessThanという名前にせざるを得ず、せいぜい「どの数字より小さいものを残すか」しか「パラメータ化(外だし)」できなかったのですが、無名関数を利用することで、データ型、およびビジネスロジックを外だしすることができ、filter関数をもっと自由に再利用できるようになったりました。

これを使って、例えばこんなことができます。


よく見ると、Predicateクラスは単に関数を入れておくために存在していますね。つまり、これは、「関数がオブジェクトとして扱われない」Javaで、無理やり関数をオブジェクトとして扱う「裏技」です。なので、実はこの裏技を使えばJavaでもHigher order functionを使うことができます。

Erlang, Python, Rubyではそもそも関数自体を最初からオブジェクトとして使ってくれるので、同じことをする場合、クラスで「ラッピング」しなくても済みます。

では、同じことをErlangでやってみます。


fun(E) -> E < 3 endが、無名関数であり、それがオブジェクトとして、Funcに代入され、filter関数の引数として渡されています。

こちらはPython。




とりあえず、Python, Erlangの方が短いですね。まぁ、それはPythonとErlangがDynamic Typingで、JavaがStatic Typingだから、というところも大きいのですが。

Javaでもこういったファンクションプログラミングをしたいという人は多く、Google Guava, Functional Javaといった、Javaでのファンクションプログラミングをやりやすくしてくれるライブラリが人気になっています(特にGuavaは、もはやJavaプログラマ必須ではと言いたくなるほど秀逸)。



What will happen with Ethereum in 30 years?

tl;dr : We will continue to have a decentralized, global chain powered by ETH, but most of the economic activities using smart contracts ...