SlideShare una empresa de Scribd logo
1 de 92
Descargar para leer sin conexión
Groovy++ 、来襲
Date: 2010/12/09
自己紹介
名前 : 杉浦孝博
twitter: @touchez_du_bois
はじめに
本日は、最近気になる OSS の Groovy++ に
ついて、
・ Groovy++ ってなに?
・何ができるの?
・ Groovy と何が違うの?
とかを語ってみたいと思います。
Groovy ってなに?
最初に Groovy とはなにか?
Wikipedia 先生に聞いてみたいと思います。
Groovy ってなに?
Groovy は JVM 上で動作する言語処理系およ
び言語の名称であり、 Java との直接的な連携
を特徴とする。 ( 略 )Groovy は動的な言語で
あり、 ( 略 )Groovy コードは内部的には
Java バイトコードに変換されて JVM 上で実
行される。 ( 略 )
動的な言語
Wikipedia 先生によると、コンパイル時に行
うことを実行時に行う高級プログラミング言
語
・コードの追加
・オブジェクトや定義の拡張
・型システムの変更によるプログラムの拡張
動的な言語のよい点
いろいろとありますが・・・
・型を書かなくてもよい ( 書く箇所が減る )
・コンパイルしないで、すぐ実行できる
動的な言語の残念な点
いろいろとありますが・・・
・実行速度が遅い
・実行してみないとコンパイルエラー的な
 エラーさえわからない
動的な言語の残念な点
動的な言語の残念な点は、 Groovy にもあて
はまります。
・実行速度が遅い
・実行してみないとコンパイルエラー的な
 エラーさえわからない
Groovy の残念な点
実行速度については・・・
・ GroovyServ で起動時間は改善できます !!
・その他は Java 化で高速に!! ...(^_^;)
Groovy の残念な点
コンパイルエラー的なエラーについて
は・・・
・ IDE でどうにかなる?
そこで
Groovy++ の登場です。
Groovy++ ってなに?
Groovy++ とは、
・ Groovy を静的型付けする拡張機能です。
Groovy++ ってなに?
つまり、
・静的な型付けにより、 Groovy が持つ動的
 言語の残念な点をある程度改善します。
Groovy++ ってなに?
Groovy++ が提供する機能はそれだけではあ
りません。
Groovy++ ってなに?
こんなものも
・ Trait
・ GrUnit
・ Tail Recursion
Groovy++ ってなに?
今回はパスします。
・ Trait
・ GrUnit
・ Tail Recursion
さっそく使ってみよう
まずはプロジェクトのページへ
http://code.google.com/p/groovypptest/
さっそく使ってみよう
プロジェクトのページです。
さっそく使ってみよう
groovypp-0.4.101.zip をダウンロードしま
す。
さっそく使ってみよう
展開して、環境変数 GROOVY_HOME と
PATH を設定します。
・ export GROOVY_HOME=/opt/groovypp-0.4.101
・ export PATH=${GROOVY_HOME}/bin:${PATH}
さっそく使ってみよう
groovy コマンドでスクリプトを実行します。


$ groovy < スクリプトファイル名 >
さっそく使ってみよう
これだけでは、 Groovy を普通に動かすのと
変わりません。
スクリプトファイルを変更する必要がありま
す。
さっそく使ってみよう
通常の Groovy プログラム


package sample


println "Hello, World!"
さっそく使ってみよう
Groovy++ 化


@Typed
package sample


println "Hello, World!"
さっそく使ってみよう
「基本的に」 Typed アノテーションを付ける
だけ。
で、どうなるの?
Typed アノテーションを付けることにより、
静的な型付がなされ、実行速度がアップしま
す!!
どれくらい速くなるの?
サンプルのクイックソート
・ Groovy : 284.758 秒
どれくらい速くなるの?
サンプルのクイックソート
・ Groovy : 284.758 秒
・ Groovy++ : 3.387 秒
  (※@Typed を付けただけ )
どれくらい速くなるの?
サンプルのクイックソート
・ Groovy : 284.758 秒
・ Groovy++ : 3.387 秒
  (※@Typed を付けただけ )
・ Java : 2.394 秒
どれくらい速くなるの?
どうなってるの?
Groovy のコードからバイトコードに変換され
るときに、「錬金術」が発動されます。
どうなってるの?
Groovy のコードからバイトコードに変換され
るときに、「 AST(Abstract Syntax Tree) 変
換」を使って、静的に型解決されたバイト
コードを生成します。
どうなってるの?
groovyc コマンドで Groovy コードをバイト
コードに変換し、 jad で生成されるバイト
コードを見てみましょう。
どうなってるの?
クイックソートのメインとなるメソッドです。
def quicksort(int[] a, int L, int R) {
   int m = a[(L+R) >> 1]
   int i=L
   int j=R
   while (i<=j) {
      while (a[i]<m) i++
      while (a[j]>m) j--
      if (i<=j) {
          swap(a, i, j)
          i++
          j--
      }
   }
    if (L<j) quicksort(a,L,j)
    if (R>i) quicksort(a,i,R)
}
どうなってるの?
@Typed 付けない場合です。
public Object quicksort(int a[], int L, int R) {
      CallSite acallsite[] = $getCallSiteArray();
      Integer m = (Integer)ScriptBytecodeAdapter.castToType(acallsite[19].call(a, acallsite[20].call(acallsite[21].call(DefaultTypeTransformation.box(L), DefaultTypeTransformation.box(R)), $const$3)), $get$$class$java$lang$Integer());
      Integer i = (Integer)ScriptBytecodeAdapter.castToType(DefaultTypeTransformation.box(L), $get$$class$java$lang$Integer());
      Integer j = (Integer)ScriptBytecodeAdapter.castToType(DefaultTypeTransformation.box(R), $get$$class$java$lang$Integer());
      do {
         if(!ScriptBytecodeAdapter.compareLessThanEqual(i, j))
             break;
         while(ScriptBytecodeAdapter.compareLessThan(acallsite[22].call(a, i), m)) {
           Integer integer = i;
           i = ((Integer) (acallsite[23].call(i)));
           Integer _tmp = integer;
        }
        while(ScriptBytecodeAdapter.compareGreaterThan(acallsite[24].call(a, j), m)) {
          Integer integer1 = j;
          j = ((Integer) (acallsite[25].call(j)));
            Integer _tmp1 = integer1;
        }
        if(ScriptBytecodeAdapter.compareLessThanEqual(i, j)) {
            acallsite[26].callCurrent(this, a, i, j);
            Integer integer2 = i;
            i = ((Integer) (acallsite[27].call(i)));
            Integer _tmp2 = integer2;
           integer2 = j;
           j = ((Integer) (acallsite[28].call(j)));
           Integer _tmp3 = integer2;
          }
      } while(true);
      if(ScriptBytecodeAdapter.compareLessThan(DefaultTypeTransformation.box(L), j))
          acallsite[29].callCurrent(this, a, DefaultTypeTransformation.box(L), j);
      if(ScriptBytecodeAdapter.compareGreaterThan(DefaultTypeTransformation.box(R), i))
          return acallsite[30].callCurrent(this, a, i, DefaultTypeTransformation.box(R));
      else
          return null;
  }
どうなってるの?
@Typed 付けた場合です。
public Object quicksort(int a[], int L, int R) {
      do {
         int    m = ArraysMethods.getAt(a, L + R >> 1);
         int    i = L;
         int    j = R;
         do     {
               if(i > j)
                   break;
               for(; ArraysMethods.getAt(a, i) < m; i++);
               for(; ArraysMethods.getAt(a, j) > m; j--);
               if(i <= j) {
                   swap(a, i, j);
                   i++;
                j--;
             }
         } while(true);
         if(L < j)
             quicksort(a, L, j);
         if(R > i) {
             R = R;
             L = i;
             a = a;
             this = this;
         } else {
           return null;
         }
      } while(true);
}
どうなってるの?
静的に解決されたコードが生成され、実行さ
れるので、速くなるのが解っていただけると
思います。
明日から
Groovy のコードに @Typed を付けまくる
ぞ!!
でも
そう簡単にはいきません
なぜ?
エドワード・エルリックという錬金術師は、
第1話「二人の錬金術師」でこう言いまし
た。
なぜ?
「つまり錬金術の基本は『等価交換』!!何
かを得ようとするなら、それと同等の代償が
必要ってことだ」
代償?
代償、ってほどでもないのですが、注意点が
あります。
代償?
@Typed を付けても、動かなかったり、動作
が変わったりする場合があります。
@Typed を付けられる位置
@Typed を付けられる位置は決まっていま
す。
・パッケージ
・クラス、インタフェース、列挙
・コンストラクタ
・メソッド
@Typed を付けられる位置
以下のコードは、


@Typed


println "Hello, World!"
@Typed を付けられる位置
コンパイルエラーになります。
org.codehaus.groovy.control.MultipleCompilationErrorsExceptio
n: startup failed:
C:Sampleex01.groovy: 3: unexpected token: println @ line
3, column 1.
  println "Hello, World!"
  ^


1 error
@Typed を付けられる位置
動かすためには、 package を指定します。


@Typed
package example


println "Hello, World!"
コンパイル時にエラー
間違ったメソッド呼び出しの場合


"Hello, World!".toStrings()
コンパイル時にエラー
Groovy は実行時にエラーになります。
Caught: groovy.lang.MissingMethodException: No signature of
method: java.lang.String.toStrings() is applicable for argument
types: () values: []
Possible solutions: toString(), toString(), toString(),
contains(java.lang.CharSequence), contains(java.lang.String),
substring(int)
   at example.ex02.run(ex02.groovy:4)
コンパイル時にエラー
Groovy++ はバイトコード変換時 ( コンパイ
ル時 ) にエラーになります。
org.codehaus.groovy.control.MultipleCompilationErrorsException:
startup failed:
C:Sampleex02.groovy: 4: Cannot find method
String.toStrings()
@ line 4, column 17.
  "Hello, World!".toStrings()
              ^
1 error
実行時に解決するものは
Groovy では問題なく動きますが、

package example


String.metaClass.p = {
   println "${delegate.size()} : ${delegate}"
}

"Hello, World!".p()
実行時に解決するものは
Groovy++ では

@Typed
package example


String.metaClass.p = {
   println "${delegate.size()} : ${delegate}"
}


"Hello, World!".p()
実行時に解決するものは
コンパイルエラーになります。

org.codehaus.groovy.control.MultipleCompilationErrorsExceptio
n: startup failed:
C:Sampleex03.groovy: 5: Cannot find property p of class
MetaClass
 @ line 5, column 18.
  String.metaClass.p = {
               ^
1 error
実行時に解決するものは
解決方法は、 @Typed を付けない
か、 @Typed(TypePolicy.MIXED) を付けます。

@Typed(TypePolicy.MIXED)
package example


String.metaClass.p = {
   println "${delegate.size()} : ${delegate}"
}

"Hello, World!".p()
実行時に解決するものは
指定できる TypePolicy は、以下のとおり
・ STATIC( 単に「 @Typed 」とした場合と同じ )
・ DYNAMIC(@Typed を付けない場合と同じ )
・ MIXED( 静的 / 動的を塩梅良くやってくれる )
アクセス修飾子
Groovy では private のプロパティ・メソッドもア
クセスできます。
package example


class Person {
   private String name
   private int age
   public Person(String name, int age) {
      this.name = name
      this.age = age
   }
   private dump() {
      println "name = ${name}, age = ${age}"
   }
}
def p = new Person("Mike", 25)
p.dump()
アクセス修飾子
Groovy++ では
@Typed
package example


class Person {
   private String name
   private int age
   public Person(String name, int age) {
      this.name = name
      this.age = age
   }
   private dump() {
      println "name = ${name}, age = ${age}"
   }
}
def p = new Person("Mike", 25)
p.dump()
アクセス修飾子
Groovy++ ではエラーになります。

org.codehaus.groovy.control.MultipleCompilationErrorsExceptio
n: startup failed:
C:Sampleex04.groovy: 19: Cannot access method
Person.dump()
 @ line 19, column 3.
  p.dump()
    ^
1 error
クロージャと final 修飾子
Groovy では
package example


def evenNum(List list) {
   def x = 0
   list.each { int it ->
       if (it % 2 == 0) {
         x++
     }
  }
  return x
}
println evenNum([1, 2, 3, 4, 5])
クロージャと final 修飾子
Groovy では正常に動作します。


$ groovy ex05.groovy
2
クロージャと final 修飾子
Groovy++ では
@Typed
package example


def evenNum(List list) {
  def x = 0
  list.each { int it ->
      if (it % 2 == 0) {
          x++
      }
  }
  return x
}
println evenNum([1, 2, 3, 4, 5])
クロージャと final 修飾子
Groovy++ ではコンパイルエラーになりま
す。
org.codehaus.groovy.control.MultipleCompilationErrorsExceptio
n: startup failed:
C:Sampleex05.groovy: 8: Cannot modify final field
example.ex05$evenNum$1.x
 @ line 8, column 13.
           x++
           ^
1 error
クロージャと final 修飾子
ロジックを変更するか
@Typed
package example


def evenNum(List list) {
   return list.findAll({ int it -> it % 2 == 0}).size()
}


println evenNum([1, 2, 3, 4, 5])
クロージャと final 修飾子
groovy.lang.Reference を使っても解決できます。
@Typed
package example


int evenNum(List list) {
  Reference x = [0]
  list.each { int it ->
      if (it % 2 == 0) {
          x++
      }
  }
  return x
}
println evenNum([1, 2, 3, 4, 5])
整数同士の割り算
整数同士の割り算ですが、

package example


println((4 / 2).class)
整数同士の割り算
Groovy では、 BigDecimal になります。

$ groovy ex06.groovy
class java.math.BigDecimal
整数同士の割り算
Groovy++ では、 int になります。
0.4.96 から 0.4.101 のどこか
で、 BigDecimal となりました。

$ groovy ex06.groovy
class java.math.BigDecimal
整数同士の割り算
次のソースは、

package example


println(4 / 2)
println(5 / 2)
整数同士の割り算
Groovy

$ groovy ex07.groovy
2
2.5
整数同士の割り算
Groovy++

$ groovy ex07.groovy
2
2 2.5
型推論
Groovy++ では、静的な型付けのため、型推
論も行っています。
型推論
例えばこのコード

@Typed
package example


def x = new Date()
println x + 1
型推論
groovyc でコンパイルし、 jad でバイトコー
ドから Java のソースに戻すと・・・
型推論
となります。

( 省略 )
   public Object run()
   {
     Object x = new Date();
     println(DateGroovyMethods.plus(((Date) (x)), 1));
     return null;
   }
( 省略 )
型推論
def ではなく Date で宣言すれば・・・

@Typed
package example


Date x = new Date()
println x + 1
型推論
となります。

( 省略 )
   public Object run()
   {
     Date x = new Date();
     println(DateGroovyMethods.plus(x, 1));
     return null;
   }
( 省略 )
他の G* なプロダクトと一緒
他の G* なプロダクトと Groovy++ を一緒に
使えるのか?
他の G* なプロダクトと一緒
Griffon と Groovy++
・試していません m(_ _)m
他の G* なプロダクトと一緒
Grails と Groovy++
・ Grails プラグインが提供されています。
他の G* なプロダクトと一緒
Grails と Groovy++
・ダウンロードページからプラグインをダウ
ンロードし、 install-plugin コマンドでインス
トールします。

$ grails install-plugin /path/to/grails-groovy-plus-plus-
0.4.101.zip
他の G* なプロダクトと一緒
Grails と Groovy++
・ Grails 1.3.6 + Groovy++ プラグイン 0.4.101
・ generate-all で生成した Controller クラスに
@Typed を付けるとどうなるか?
・ create-xxx で生成した Domain Class や
Service クラスに @Typed を付けるとどうなるか?
他の G* なプロダクトと一緒
Grails と Groovy++
・作成した Controller クラスや Service クラス
に、 @Typed(TypePolicy=MIXED) を付けます。
・ @Typed だと、 redirect メソッドや render メ
ソッドでコンパイルエラーになります。
他の G* なプロダクトと一緒
Grails と Groovy++
・ Domain Class の場
合、 @Typed(TypePolicy=MIXED) でも、 @Type
でも、 constraints でエラーになります ...orz
まとめ
まとめ
・ Groovy++ は、 Groovy を静的に型付する
拡張機能です。
まとめ
・ Groovy++ は、 Groovy を静的に型付する
拡張機能です。
・基本的に @Typed を付けるだけです。
まとめ
・ Groovy++ は、 Groovy を静的に型付する
拡張機能です。
・基本的に @Typed を付けるだけです。
・でも「錬金術」なので、 Groovy との違い
に気をつけてください。
発表は以上です。
質問、意見、ご要望が
ありますでしょうか?
以上、ご清聴ありがと
うございました。

Más contenido relacionado

Similar a Groovy++、来襲

Ленивые итераторы для разбора разнородных данных. Михаил Озеров. Moscow.pm 6 ...
Ленивые итераторы для разбора разнородных данных. Михаил Озеров. Moscow.pm 6 ...Ленивые итераторы для разбора разнородных данных. Михаил Озеров. Moscow.pm 6 ...
Ленивые итераторы для разбора разнородных данных. Михаил Озеров. Moscow.pm 6 ...Moscow.pm
 
Observando lo observable (de t) CodeCamp 2010
Observando lo observable (de t) CodeCamp 2010Observando lo observable (de t) CodeCamp 2010
Observando lo observable (de t) CodeCamp 2010Corvalius
 
Embedded Probabilistic Programming
Embedded Probabilistic ProgrammingEmbedded Probabilistic Programming
Embedded Probabilistic ProgrammingRyosuke TAKASHIMA
 
東京Node学園#1「非同期プログラミングの改善」のエッセンス
東京Node学園#1「非同期プログラミングの改善」のエッセンス東京Node学園#1「非同期プログラミングの改善」のエッセンス
東京Node学園#1「非同期プログラミングの改善」のエッセンスkoichik
 
Lecture7
Lecture7Lecture7
Lecture7orgil
 
UglifyJS 使用文档
UglifyJS 使用文档UglifyJS 使用文档
UglifyJS 使用文档明 李
 
BOF1-Scala02.pdf
BOF1-Scala02.pdfBOF1-Scala02.pdf
BOF1-Scala02.pdfHiroshi Ono
 
How did yarv2llvm fail
How did yarv2llvm failHow did yarv2llvm fail
How did yarv2llvm failmiura1729
 
帰って来たNemerle
帰って来たNemerle帰って来たNemerle
帰って来たNemerleKota Mizushima
 
FISL11 - REST com Java - WebServices Simples e Ágeis
FISL11 - REST com Java -  WebServices Simples e ÁgeisFISL11 - REST com Java -  WebServices Simples e Ágeis
FISL11 - REST com Java - WebServices Simples e ÁgeisEdgar Silva
 

Similar a Groovy++、来襲 (12)

Ленивые итераторы для разбора разнородных данных. Михаил Озеров. Moscow.pm 6 ...
Ленивые итераторы для разбора разнородных данных. Михаил Озеров. Moscow.pm 6 ...Ленивые итераторы для разбора разнородных данных. Михаил Озеров. Moscow.pm 6 ...
Ленивые итераторы для разбора разнородных данных. Михаил Озеров. Moscow.pm 6 ...
 
Observando lo observable (de t) CodeCamp 2010
Observando lo observable (de t) CodeCamp 2010Observando lo observable (de t) CodeCamp 2010
Observando lo observable (de t) CodeCamp 2010
 
Embedded Probabilistic Programming
Embedded Probabilistic ProgrammingEmbedded Probabilistic Programming
Embedded Probabilistic Programming
 
東京Node学園#1「非同期プログラミングの改善」のエッセンス
東京Node学園#1「非同期プログラミングの改善」のエッセンス東京Node学園#1「非同期プログラミングの改善」のエッセンス
東京Node学園#1「非同期プログラミングの改善」のエッセンス
 
Lecture7
Lecture7Lecture7
Lecture7
 
UglifyJS 使用文档
UglifyJS 使用文档UglifyJS 使用文档
UglifyJS 使用文档
 
BOF1-Scala02.pdf
BOF1-Scala02.pdfBOF1-Scala02.pdf
BOF1-Scala02.pdf
 
Ejercicios resueltos de java
Ejercicios resueltos de javaEjercicios resueltos de java
Ejercicios resueltos de java
 
How did yarv2llvm fail
How did yarv2llvm failHow did yarv2llvm fail
How did yarv2llvm fail
 
帰って来たNemerle
帰って来たNemerle帰って来たNemerle
帰って来たNemerle
 
FISL11 - REST com Java - WebServices Simples e Ágeis
FISL11 - REST com Java -  WebServices Simples e ÁgeisFISL11 - REST com Java -  WebServices Simples e Ágeis
FISL11 - REST com Java - WebServices Simples e Ágeis
 
MS Swit 2010
MS Swit 2010MS Swit 2010
MS Swit 2010
 

Más de Takahiro Sugiura

Más de Takahiro Sugiura (9)

Closures and methodMissing are real
Closures and methodMissing are realClosures and methodMissing are real
Closures and methodMissing are real
 
Introduction to Spock
Introduction to SpockIntroduction to Spock
Introduction to Spock
 
GContractsの基礎
GContractsの基礎GContractsの基礎
GContractsの基礎
 
GroovyからAnime
GroovyからAnimeGroovyからAnime
GroovyからAnime
 
Vert.x.tari.tari
Vert.x.tari.tariVert.x.tari.tari
Vert.x.tari.tari
 
Okiraku!
Okiraku!Okiraku!
Okiraku!
 
もしトラ
もしトラもしトラ
もしトラ
 
ジャパネットQB GPars
ジャパネットQB GParsジャパネットQB GPars
ジャパネットQB GPars
 
Tokyo Sky Tree
Tokyo Sky TreeTokyo Sky Tree
Tokyo Sky Tree
 

Groovy++、来襲