K.Maebashi's BBS 投稿フォーム
ハンドル名
件名
Link
>今回の投稿は、説明の都合上、大分長くなってしまいました。迷惑でしたら、 >すいません。 > >>やってみるとそんなに難しくはないんですよね。実際、今回の企画はそれを >>示そうと思ってはじめました。時間がなくてなかなか思うに任せていませんが。 >># そんなに難しくはない、ということを示したいんだから、あっという間に >># 実装できた方が説得力あるんでしょうけどねえ。 > >簡単に実装するなら、Lisp系言語などが楽でいいのではと思いましたが、 >どうでしょうか。普通の言語に比べて、構文がちょっと特殊ですが、機能 >拡張がわりと容易ですし、言語設計の面白さは十分に味わうことができるの >ではないかと思います。 > >>・委譲の言語仕様とか、 > >基本的なアイデアとしては、いわゆる「単純委譲」をコンパイラが自動生成する >というもので、Java風に書くと、 > >class MyList{ > forward List list_ = new ArrayList();//委譲宣言 >} > >というコードから、 > >class MyList{ > List list_ = new ArrayList(); > public void add(Object o){ > list_.add(o); > public Object get(index i){ > return list_.get(i); > } >} > >というコードをコンパイラが生成します。もちろん、これだけだと >メソッド名が衝突したときに問題が発生しますが、経験から言って、 >そのような衝突は、おそらくさほど頻度は高くないだろうと思われるので、 >コンパイルエラーにして、衝突したメソッドのみ、プログラマにどのフィールドに >委譲するか(あるいはそもそも委譲せず、そのメソッドを新たに定義するか)を >選択させれば良いと考えています。 > >あと、全部のメソッドを委譲するだけでは不便なので、委譲したくないメソッドを >列挙する機能も必要かなと考えていますが、これはまだ実装するかどうかわかり >ません。 > >>・クロージャの実装方法(環境へのアクセス方法)とか、 > >実は、クロージャの部分はまだ実装できていないのですが、仕様は大体決まって >いて、クロージャは、新たなデータ型を導入するのではなく、インタフェース >の実装クラスのインスタンスとして、クロージャを生成するという方法を >取ろうと思っています。 > >ActionListener n = #(ActionEvent event){ > System.out.println("actionPerformed"); >}; > >というコード(#以降がクロージャの定義で、eventはクロージャの仮引数です)は、 > >class ActionListener$1 implements ActionListener { > public void actionPerformed(ActionEvent event){ > System.out.println("actionPerformed"); > } >} >... >ActionListener n = new ActionListener$1(); > >というコードにコンパイルされます。 > >ここでは、ActionListenerがメソッドを1つしか持っていないため、クロージャ >の定義では、メソッド名を指定する必要はありませんが、メソッドを複数持った >インタフェースの場合、対応するメソッドを指定する構文を用意しようかと >思っています。 > >で、問題になっている環境へのアクセス方法ですが、クロージャから外側の >環境にアクセスしていることをコンパイラが検出したら、外側の環境での変数 >へのアクセスをObject型配列の要素に対するアクセスに変換して、Object型配列 >への参照を、クロージャに渡すという方法を取ります。例えば、 > >class Hoge{ > public static void main(String[] args){ > int n = 0; > ActionListener listener = #(ActionEvent event){ > n++; > }; > listener.actionPerformed(null); > System.out.println("n: " + n); > } >} > >というコードは、 > >class ActionListener$1 implements ActionListener { > private Object[] environment_; > ActionListener(Object[] environment){ environment_ = environment; } > public void actionPerformed(ActionEvent event){ > environment_[0] = new Integer(((Integer)environment_[0]).intValue() + 1); > } >} > >class Hoge{ > public static void main(String[] args){ > Object[] environment = new Object[1]; > ActionListener listener = new ActionListener$1(environment); > listener.actionPerformed(null); > System.out.println("n: " + ((Integer)environment[0]).intValue()); > } >} > >というコードにコンパイルされます。このようなクロージャの実装方式は、 >クロージャを新たなデータ型として導入するのに比べて、正直使い勝手は >悪いですが、既存のライブラリを活用するという点では、この方式の方が >良いのではないかと思っています。 > >>・型宣言を省略する方法とか(静的型とのことなので、レキシカルな最初の代入から推測?) > >その通りです。例えば、以下の代入があったとして、 > >n = 1; > >代入があった時点でのスコープで、nが宣言されてされていなければ、それは > >int n = 1; > >という宣言とみなされます。代入される値の型が参照型の場合も、同じですが、 >nullが代入される場合だけやや特殊で、 > >n = null; > >は、 > >Object n = null; > >とみなされます。この機能があれば、例えば、よくある > >String line; >while((line = reader.readLine()) != null){ > .. >} > >というコードが、変数宣言無しで、 > >while((line = reader.readLine()) != null){ > .. >} > >だけで書けるようになります(lineのスコープはwhile文で閉じています)。 > >以上、長々と説明を書かせていただきましたが、よろしければツッコミや >意見をいただければ幸いです。 > >> 公開される日を楽しみにしています。 > >どうも有難うございます。頑張って開発を進めたいと思います。
spamよけのため、ここに「ほげぴよ」と入力してください。
削除パスワード :
クリック!