Io
最近ちょくちょくあちこちで話題になっているインスタンスベースのオブジェクト指向プログラミング言語。
デザインパターン的にはプロトタイプパターンなので、プロトタイプベースといわれていましたが、「プロトタイプ」という語感が開発プロセスの「プロトタイピング」と誤解されやすいので最近はインスタンスベースつってますね。
インスタンスベースのなにが面白いかっていうと、クラスじゃなくてインスタンスからあたらしいインスタンスを作るという点。
インスタンスをつくるときにもとのインスタンスをクローンして作るわけです。
クラスは存在していなくて、インスタンスしかないという。 ようはずべての要素がインスタンスとして生きているまま動くわけです。
Ioのさらに面白い点は差分プロトタイプベースだということ。 この点はApple のPDAであるNewton用の言語NewtonScriptから影響されている点ですね。これはIoのドキュメントにもそう記述されています。
継承はスロットを追加したインスタンスのリンクにより実現するわけです。 Ioのそこら編の仕様はまだちょっと読み取れてないんですが、NewtonScriptでは2つの継承方法があってペアレント継承とプロトタイプ継承があります。
その2本の継承ラインで多重継承するわけですが、継承自体はただのインスタンスリンクなわけです。で、メッセージパッシングとしてはそのリンクをたどって適合するスロットをヒットして実行、あるいは代入、取得などを行うわけです。
PDAはメモリー容量が少ないんで、NewtonではROM上にプロトタイプを沢山もっていて、それをちょこっとだけ差分を追加してプロトタイプ継承して実行するようなやりかたをしていることでメモリー効率がとても高いオブジェクト指向言語の実行環境を構築できていたわけです。
実際のNewtonScriptのソースコードはほんのすこしの記述で相当なことができるということ実行時のメモリー消費の少なさはJavaとはくらべようもないぐらい効率がいいです。 実際NewtonScriptのアプレットは大きいものでも100kを超えることはほとんどありません。
バイトコードで動くというコンセプトをJavaよりも遥か前にコンシューマ製品に実用化していたという点も先取りしていますね。
まぁ、最近はメモリー安いんであんまり重要じゃないかもですが、速度にクリティカルなものはメモリー効率が速度に影響するので、インスタンスベース言語の意義があるかもしれません。
あと言語が簡易であるということとSmallTalkばりのメッセージパシングの仕組みが柔軟性とプログラミングの容易さをうみだしていると思います。
NewtonScriptのGNUプロジェクトもありますが、軽い点でIoに期待もてそう。
Io 日本語翻訳ドキュメント
http://f21.aaa.livedoor.jp/~kizz/prog/io/Docs_ja.html
Javaでプロトタイプパターンで全部実装してメッセージパシングの方式をシミュエートしてみても面白いかもしれません。
JavaAPIは全部ファイナルのクラスでラッピングして、スタティックでインスタンス化しておいて、コンストラクタはプライベートにしておきます。 APIのインスタンスがほしいときには、プロトタイプのインスタンスにクローンくださいってメッセージをパスします。
メソッドはすべてプライベートで書いておいて、共通の基底クラスに、メッセージを受け取るパブリックのメソッドがあって、メソッド名の文字列でうけとって、リフレクションでプライベートメソッドを探して実行します。
そのインスタンスに存在しなかったらインスタンスリンクをたどってメッセージをパスします。
おもしろいけど、意味ないか。
public abstract class PrototypeBase { private PrototypeBase myProto; //プロトタイプ継承の親へのリンク private PrototypeBase myParent; //ペアレント継承の親へのリンク //クローン抽象メソッド (テンプレートメソッドパタン) protected abstract PrototypeBase clone(); //コンストラクタ protected PrototypeBase( PrototypeBase proto, PrototypeBase parent ) { myProto = proto; myParent = parent; } //メッセージパッシングにより呼び出すのでプライベート private PrototypeBase newInstance() { ret = this.clone(); ret. myProto = myProto; ret. myParent = myParent; return ret; } //メッセージパスメソッド public PrototypeBase passMessage( String message, PrototypeBase[] args ) thows NoSuchMethodException { //自分のインスタンスのメッセージにあうメソッドを検索して実行 ... //なかったらmyParentのリンクにメッセージをパス try { if( myParent != null ) ret = myParent.passMessage( message, args ); } catch( NoSuchMethodException e ) { //そこにもなかったらmyProtoのリンクにメッセージをパス if( myProto != null ) ret = myProto.passMessage( message, args ); } return ret; } }
だからなんだっていわれそう。(笑)