uehaj's blog

Grな日々 - GroovyとかGrailsとかElmとかRustとかHaskellとかReactとかFregeとかJavaとか -

[groovy][gep] 静的コンパイルのGroovy拡張提案(GEP10)が出た

次期Groovyの新機能についての情報です。静的型チェック(STC, Statically Type Check)がGroovy 2.0 beta 1トランクに含められたのに続き、静的コンパイルのためのGroovy拡張提案(groovy enhancement proposal)、GEP10が提示されました。

静的コンパイルはAST変換アノテーション「@CompileStatic」を指定することで駆動されます。コード例はこんな感じ。

@groovy.transform.CompileStatic
int fib(int i) {
    i < 2 ? 1 : fib(i - 2) + fib(i - 1)
}

現時点でこれがコンパイルでき、Java並みの速度で動くそうです(ただしそれが可能となるコードがソースリポジトリにコミットされているかは不明)。DefaultGroovyMethodsすなわちGDKのメソッド呼び出しや、演算子経由のメソッド呼び出し(+でplusが起動されるなど)は未対応だそうです。

静的型チェック(STC)は、意図的に矮小化して言うと、実行できるGroovyプログラムが減る(正しいGroovyプログラムをサブセット化する)だけのもので、動的な機能を使わない・もともと型エラーを含まないGroovyプログラムには全く影響を与えないものでした。

しかし、静的コンパイルはGroovyプログラムの実行速度が(場合によって劇的に)変ってくるものです。確かに原理的には「速度が必要なところはJavaで書いて組みあわせれば良い」のですが、実際には苦労もあるでしょう。@grabで済んでいたのが、mavenが必要になるのが嫌! とか。

ということで、実行速度向上のための静的コンパイルはやはり望まれるのです。例えinvokeDynamicが導入されるとしても、です。なぜならそれの速度がわからないし、実用的な速度のものが普及するのは当分先と見てよいからです(とGEP10に書いてあります)。

今のGEP10の内容は、「こう作るよ」というものではなく、どう実装したら良いだろうか?を案ベースで問い掛けています。例えば

  1. 静的コンパイル時に、メソッドはJavaGroovy++のように静的に結合するのか、(マルチメソッドが効かなくなるなどのGroovyコードの意味が変わってしまう)
  2. STCで「フローセンシティブ」に型付けしていたように、フロー解析でメソッドが特定できた場合だけ静的結合させるのか、
  3. 新しい演算子(例えば)「->」を導入し、obj->method()のように書いたときだけ静的結合するのか

など。議論ははじまったばかりです。議論はgroovy-devのMLでやってます。