Javaのクロージャいじってみた(3)

5.カリー化
  メソッド内無名クラス定義ではfinal修飾子をつけたローカル変数を
  無名クラス内部で利用することができるが、これを利用して
  カリー化を実現している...みたい。

  マイコミジャーナルの記事 にクロージャ内で利用したいローカル
  変数には@Sharedアノテーションをつけることで利用可能になる
  という記述があった。
  へー
  てっきり無名クラスのシンタックスシュガーだからfinalにしないと
  駄目かと思っていたけど、ちょっと違うのね。

  ……?あれ?私の試しているクロージャ実装(*1)ではfinalにも@Shared
  つけなくてもコンパイル通るぞ??このバージョンの実装では文句は
  言わないのかな?それとも@Sharedはクロージャのための機能じゃない
  からjava7入れないとだめとか?

  (*1 JDK1.6.0_10_bate, BGGAプロトタイプ実装2008-07-07版)

  例)
  javaクロージャでカリー化

//int local = 2; <-- うちのではこれも通った。
final int local = 2;
{int=>int} func = { => {int num => num / local } }.invoke();
func.invoke(10); // 結果=5

  上記コードの逆コンパイルコード

final byte local = 2;
II ii = (II)(new O() {
public final II _2B_invoke() {
return new II() {
public final int _2B_invoke(int i) {
return i / local;
}

public final int invoke(int i) {
return _2B_invoke(i);
}

final _cls1 this$1;

{
this$1 = _cls1.this;
super();
}
}
}

public final II invoke() {
return _2B_invoke();
}

public volatile Object invoke() throws Throwable {
return invoke();
}

final int val$local;
final SimpleClosure this$0;

{
this$0 = SimpleClosure.this;
local = i;
super();
}
}
).invoke();

  逆コンパイルすると2段のインナークラスが生成されることがわかる。
  想像通りですな。
  このクロージャを返すクロージャってクロージャ利用の主流になりそう
  な予感。

  カリー化というものを理解している自信ないかも。書き方はいいとして、
  使いどころとか自信ない。オブジェクト指向なら、カリー化とか
  言わなくてもアクセサと処理実行メソッドを分けることで効果は同じ
  なんじゃないの?とか思ったり。

// こんなの
func.set(arg1);
func.invoke(arg2);

  最近のトレンドは関数型言語の考え方取り入れることなんですかね?
  RubyといいC#といい、boost libraryといい、あちこちで見かける。
 
 

コメント

このブログの人気の投稿

java7のロードマップ

リフレクション無しにjar間のクラスを解決する作りこみ

Arrays.asList()のジェネリクスの仕組み