JavaScriptプログラマって意外とAdaの事好きなんじゃないの?

JavaScriptのOOPとAdaのOOPはもの凄く似ているという説がありまして、実はスムーズに移行できるのではないかと思うわけです。

例えばJavaScriptで適当なクラスを作ってみる。

function Klass(initialValue) {
    this.var = initialValue;
}

Klass.prototype.method = function(arg) {
    for (var i = 0; i < arg; i++) {
        console.log(this.var);
    }
};

var instance = new Klass(17);
// ドット記法ならプロトタイプチェインを自動で検索してくれる
instance.method(3); // -> 17 17 17
// あるいはcallで。この場合プロトタイプチェインは働かない
Klass.prototype.method.call(instance, 3); // -> 17 17 17

// prototypeを無視してもメソッドが定義出来る
function another() {
    console.log(this.var - 6);
}
another.call(instance); // -> 11

同じ事をAdaで書くとこんな感じ。コード自体が短いのでパッケージ宣言がゴミゴミして見えますが、実用的なコードだと問題にはならないです。あと、無駄にaccessを使ってる気がしないでもないけれど、これは雰囲気重視で。

with Ada.Text_IO; use Ada.Text_IO;
procedure Prototype is

   package Klass is
      type Klass_Type is tagged limited
         record
            Var : Integer;
         end record;

      procedure Method (This : not null access Klass_Type'Class;
                        Arg  : Integer);
   end Klass;

   package body Klass is
      procedure Method
        (This : not null access Klass_Type'Class;
         Arg  : Integer) is
      begin
         for I in 1 .. Arg loop
            Put_Line (Integer'Image(This.Var));
         end loop;
      end Method;
   end Klass;


   Instance : access Klass.Klass_Type;
begin
   Instance := new Klass.Klass_Type'(Var => 17);
   -- Ada05だとドット記法で書ける!
   Instance.Method(3); -- -> 17 17 17
   -- あるいは単にメソッド呼び出しで。
   Klass.Method (Instance, 3); -- -> 17 17 17

   -- パッケージを無視してメソッド定義
   declare
      procedure Another (This : not null access Klass.Klass_Type'Class) is
      begin
         Put_Line (Integer'Image(This.Var - 6));
      end Another;
   begin
      -- この場合ドット記法は使えない
      Another(Instance); -- -> 11
   end;
end Prototype;

やばい似てますね。メソッドとクラスが実は無関係な雰囲気というか、実際はObject(record)を適当なメソッドに投げているだけ的な雰囲気というか。今回は省きましたけど、パッケージを使った継承の仕組みもなんとなく似てます。

JavaScriptな人は試しにAdaを使ってみると結構なじみやすいんじゃないかなぁと思うわけです。