Javaでは、すでに定着した標準のinterfaceにメソッドを追加することはできません。
Listにメソッドを追加すると、それまでにListを実装していたライブラリは全滅になります。
なので、上記のeachの実装ではコンパイラの段階でスタティックメソッドに変換するようにしてるのですが、こういった変換を一般的に定義できる文法があれば、ユーザーがライブラリにオレメソッドを追加できるようになります。
なので、こんなのはどうでしょう?
public @attach java.util.List{ void each(Closure c){ for(Object item : this) c.process(item); } }
という定義をすると
class _List{ static void each(List _this, Closure c){ for(Object item : _this) c.process(item); } }
というクラス定義になって
List items = xxx; items.each({print(item);});
を
List items = xxx; _List.each(items, {print(item);});
に変換してくれるような構文。
つまり、シンタックスシュガーを定義できる構文です。
実際にはこのままだとオーバーライドができないので、生成される処理としては
class _List{ static void each(List _this, Closure c){ if(_this.getClass().hadMedhod("each")){ _this.getClass().getMethod("each").invoke(_this, c); return; } for(Object item : _this) c.process(item); } }
みたいにオブジェクトがメソッドをもっているかどうか判定する前処理が必要になります。
追記:
問題点は、衝突の問題とスクリプトから呼び出すときの問題。
スタティックJavaで考えると、問題はコンパイル時だけなので、適切にコンパイラに情報与えるだけでいいので問題なし。
やっかいなのは、スクリプトから呼び出すときの衝突。
スクリプトから呼び出すために、ランタイムでもなんらかの情報を保持しておく必要があるけど、そのときに衝突があった場合の優先度をどう決めるか問題。