class

xtalはクラスベースのオブジェクト指向言語です。試行錯誤中はプロトタイプベースだったりした時期もあったのですが、クラスベース全盛の昨今では受け入れられないだろうと思いなおしクラスベースとなりました。*1

xtalでclassはclass式で生成します。インスタンス変数はRuby風に@を前置します。

Foo: class{
  // 初期値を伴わないインスタンス変数の定義
  @bar;

  // 初期値を伴うインスタンス変数の定義
  @value: 10;

  // 上で定義したインスタンス変数にもアクセスできる
  @data: [@value, @value+1, @value+2];

  // 上の初期値は、下のinitialize関数が呼ばれる前にセットされます。
  
  // インスタンス生成時に呼ばれるメソッド
  initialize: method(v){
     @bar = v;
  }

  p: method(){
    %f(bar:%s, value:%s, data:%s)(@bar, @value, @data).p;
  }
}

// インスタンスの生成は、Foo()というようにクラスを関数呼び出しします。
f: Foo("test");

// bar:test, value:10, data:[10,11,12] と表示される
f.p;

// Fooを継承する
// class(SubClass1, SubClass2) とすれば多重継承も可能
Boo: class(Foo){  
  initialize: method(v){
    // Fooのinitializeを呼び出す
    Foo::initialize(v);
  }
 
  p: method(){
    "Boo::p".p;
    Foo::p();
  }
}

Boo("BOO!").p;

RubyPython等と違い、xtalではインスタンス変数を後から追加することは出来ません。またインスタンス変数は完全にprivateで、さらにクラス内部で定義されたメソッドからしかアクセスできません。
これらの制限により、もし存在しないインスタンス変数を参照しようとすれば、コンパイルエラーとして出すことができます。また変数アクセスも速く実装できるなど、利点が多いと思っています。


xtalのclassは名前空間的にも使用します。以前はRubyのようにmoduleが存在したのですが、classとmoduleにあまりに違いが無いと感じ、統一することにしました。

*1:世の中のプロトタイプベースの言語は、大抵クラスベースとして扱えるようなライブラリが出ています。プロトタイプベースはドキュメントが書きづらいという話もどこかで聞きましたが、その通りだとも思いました。