今日の役に立たない一言 - Today’s Trifle! -

古い記事ではさまざまなテーマを書いていますが、2007年以降はプログラミング関連の話がほとんどです。

Java とクロージャ

匿名クラスに対してたくさんの貴重なコメントをありがとうございます。
さて、もう一度整理。まず最初に、クロージャとはなにか。個人的にはクロージャ(をサポートしている言語)をあまり使ったことがないので、あまり突っ込んだ議論ができない。
まあ、とりあえず引用。クロージャとはどういうものか、は http://capsctrl.que.jp/kdmsnr/wiki/bliki/?Closures の中で簡潔にまとめられている。

クロージャはコードブロックである。 かつ、クロージャのある環境と結びつくことができる。
(略)
2つ目の違いは、それほど形式的に定義はされていませんが、大変重要なことです。 これがないと、実際に使ってられないからです。 クロージャをサポートする言語は、簡単なシンタックスクロージャを定義できます。
(略)
ローカル変数と結びつけることできるというのも、 クロージャが頻繁に使われる理由のひとつでしょうが、 いちばんの理由は、記法がシンプルで明快だからだと思います。

Martin Fowler も述べているとおり、記法がシンプルで明快であることが重要だと思う。コードのシンプルさは可読性と直結している。
nakamura さんが紹介してくれたhttp://joe.truemesh.com/blog//000390.htmlを見ても分かるように、静的型言語でクロージャをサポートしてもこれが限界。可読性はJavaで無名クラスを使ったときと大差ない。型を教えてあげないとコンパイラが怒るし、return も省略できない。これは Java でも同じことが言える。Ruby のコードはとても直感的だけど、C#のコードはとても直感的とはいえない(直感的だと捉える人もいるかもしれんが)。
それはまさに、nakamuraさんが指摘した、

何してるか判り難いのは、(乱暴にいえば)actionPerformedとかのメソッド名がちらちら目に入って意識を撹乱してるんじゃないかな。
能書きが長ったらしいと注意力を散漫にさせられてしまいがち。
GroovyみたいにスッキリClosureを書ける状況だと、あまり苦にならないのではないかと。

というのがピンポン!だと思う。
例えば、Java でも

    File files[] = new File(dir).listFiles();
    Arrays.sort(files, {|f1, f2| f1.length() - f2.length() } as Comparator);

みたいな書き方ができるとすれば使いようがあると思うんだけど、public int compare とか public boolean equals とか return を書かないと、きっとコンパイラは許してくれない。
だとしたら、無理してクロージャや無名クラスを書くよりも、

    File files[] = new File(dir).listFiles();
    Arrays.sort(files, new FileSizeComparator());

の方がわかりやすいと思わない?