うさぎ組

ソフトウェア開発、チームによる製品開発、アジャイル、ソフトウェアテスト

Groovyは衰退しました #gadvent2012

G* Advent Calendarの9日目になります。
G* Advent Calendar 2012 : ATND

前はid:touchez_du_bois さんのAST変換の無駄使い - とある技術の謹書目録です。
次はid:fumokmm さんです。

マニアックな話を書きます。とATNDに書いたのですが、高度とかではなくてですね。誰も書かなさそうなものをちょこっとかいてみようかなぁと。
タイトルに特に意味はない。という元ネタすら知らないです。(おい
あ、以下の文章はGroovyをdisっているように見えるかもしれません。disっているので気にしないでください。Advent CalendarでまさかのGroovyDis。。。
でも、僕はGroovy本当に大好きです。
I Love Groovy!!

Groovyの静的コンパイルがイケてない

Groovyは2.0になり静的コンパイルができるようになりました。
クラスやメソッドアノテーションを指定するだけで、そのクラスやメソッドに対して静的に型チェックをしてコンパイルします。
Javaとだいたい同じくらいの型安全性が手に入り、ほとんどJavaと同じレベルのパフォーマンスを出せるようになります。


どれくらい型を書かないといけなくなるかという話なのですが、メソッドの引数や返り値の型を指定しなければいけない場合がほとんどです。

ただし、メソッド内では変数の型宣言をしなくてよい感じです。つまり次の感じが静的コンパイルなGroovyになります。

import groovy.transform.CompileStatic

@CompileStatic
class Foo {
    def fooMethod(String target){
      def result = target * 3 // 型推論が効く
      result.contains("G*") // 型推論によってresultはStringなのでcontainsが存在するとわかる
    }
}


これですね。Groovyらしくないというかですね。いや、なんというか何らしい?って聞かれると
C#
っていう。
defがvarになればほとんどC#ですよ。これ。ローカル内でのみ型推論がきくとかもふくめて。

でも、これがまた不完全でして。
次のはコンパイルが通るし、実行できます。

import groovy.transform.CompileStatic

@CompileStatic
class Foo {
    def fooMethod(String target){
      def result = target * 3 // 型推論が効く
      result = 1 // String型だったresultに1を代入できる
      println result
    }
}

これ、直感的にはコンパイルエラーがはいってほしいです。はい。
なんというか、選択的に型付けできるのは素晴らしいのですが、もうちょっと。こう。がんばれ!


Groovyにマクロが!

最初はdefがどのように動作しているのかというか、defとはどのように解釈され、どのようにバイトコードに落ちるのかという話を延々と書こうとしていたのですが、面白い?ものを見つけた!
まぁ見つけただけでどうという話はないので、知っている方いたら詳しく教えてください!という話なんですが。



Groovyは自身がもつキーワードというのをTypes.javaというファイルで定義しています。あと演算子もですね。
forといったものから、==~まで定義しています。
で、ここでdefももちろん含まれているのですが、次のようなですね。

        addKeyword( "continue"    , KEYWORD_CONTINUE            );
        addKeyword( "def"         , KEYWORD_DEF                 );
        addKeyword( "defmacro"    , KEYWORD_DEF                 ); // xxx br defmacro
        addKeyword( "default"     , KEYWORD_DEFAULT             );


上から3行目です。
見て思いましたね。これ、Clojureでしたっけ?と。
で、そのあと延々とGroovyのコードを見ていたのですが、このdefmacro使われていません。
なんだ!そして、この後ろのxxx br defmacroって何を意味しているのでしょうか?
英語でよくある表現なのでしょうか。。。?知っているかたいたら教えてください。

で、実際にこのdefmacroをいろいろ使ってみたのですが、どのタイミングで使ってもMethodMissingになってしまいました。
何に使うつもりだったんだ。。。gotoは歴史的経緯で単なる予約語となっていますが、defmacroの歴史的経緯とは。。。って感じです。
defと同じものとして解釈するようなように見えるのでもしかしたら、独自ASTを定義したときにそのなかで「defとは違うキーワードでdefと同じ動作をさせたい」というのがあれば使えるの「かも」しれません。
ASTで使ってみればもう少しわかりそうな気がします。はい。
ということで、Groovyにはマクロはありませんでした。
でも、ASTBuilderとかでASTを気軽にいじれるようになっているので、それがマクロとかって言われればまぁまぁ。。。というお茶を濁す感じにはもっていけそうですね。



最後に

いまさらながら気付いたのですが、Groovy2.0用にGroovy++を書き換えて公開しました!というのをやって、書いた方が楽しかったような。。。
正直なところ、Groovy++ さんすごいのでよいです。traitとかもありますしね。
まぁGroovyはどん欲に機能を取り込むのが好き(trampolineとか)なので、コードを読んでいるとすごく心が折れそうになりながらも楽しいです。
あと、バグをなかなか直してくれないとかもあるのでなんとかしたいですねー。来年はGroovy本体にいろいろpull reqを投げようと思います。


なんだかんだいいながらですが、Groovyはすごく便利ですし、GradleやSpockといった素晴らしいツールフレームワークもありますのでぜひぜひ使ってみてください。


どうでもいいこと

場所にもよりますが、AdventCalendarとかblogというのは気軽に書いておけばいいと思います。
今回のエントリもあんまり気張らずにさらっと書いてみるっていうノリで書いてみました。
みなさんもっと気軽書いてみていろんな機会を得てみてはどうでしょうかね。