Xtendを触ってみる その9 クロージャのカリー化(というか部分適用)

XtendではメソッドはそのままJavaメソッドに変換されるのですが、クロージャは特別で引数の数に応じてFunction0〜Function6オブジェクトに変換されます。なので引数の数が7つ以上のクロージャを作ることはできませんw(コンパイルエラーになります)
で、Function0〜Function6にはFunctionExtensionsによってカリー化(なんちゃってカリー化ですが)のための拡張メソッドが追加されます。こんな感じで使います。

val func = [ String s1, String s2 | s1 + " " + s2 ]

// 普通に呼び出す
println(func.apply("Hello", "World!"))

// 第一引数を部分適用
val curried = func.curry("Hello")
println(curried.apply("World!"))

実際やってることはなんとなく想像がつくと思いますが、第一引数を束縛してFunction2をFunction1でラップしているだけです。カリー化じゃなくて部分適用ですね。複数の引数を適用する場合はこんな感じです。

val curried = func.curry("Hello").curry("World!")
println(curried.apply())

もちろんcurryメソッドが使えるのはクロージャ(Function0〜Function6)に対してだけなので、普通のメソッド呼び出しをカリー化することはできません。Xtendのクロージャの使い道ってコールバック関数を渡したい場合がほとんどだと思うのですが、カリー化したい関数は逆に引数にクロージャを取る関数が多いわけで、そもそもカリー化じゃないよ!という突っ込みは置いておくとしても、使い道がなさそうな気が…。

まとめ

というわけで、最後がなんだか微妙な感じのエントリになってしまいましたがXtendを触ってみるシリーズはこれでお終いです。Xtendは言語としては正直あまり目新しい部分はないのですが、ディスパッチメソッドと拡張メソッドの組み合わせと、DIで拡張メソッドの実装を差し替えることができるというコンセプトは面白いなと思いました。
最近Scalaのパーサコンビネータを使ってなんちゃってCommon Lispを作っているのですが、関数をDIで差し替えるというアイデアを取り入れられないかなぁと考えたりしています。
ただ、ちゃんと見ていくと全体的にはやはりXtextの使用例の域を出ていないのかな、という印象です。もともと機能をかなり絞っているのでJavaの置き換えになるような言語ではないのは明らかなのですが、補助的に使うにしてもぶっちゃけJavaより多少短く書けるというだけで、それほど大きなメリットがあるようには思えません。現段階ではXtextの例としては非常にインパクトがあるとは思いますが、単独のプログラミング言語としては中途半端な存在と言わざるを得ません。
とはいえ、今後進化していく可能性もあると思うので、引き続きウォッチしていこうと思います。