Ola Bini氏(リンク)は、JRuby (リンク)開発の中心人物であり、Practical JRuby on Rails Projects(リンク)の著者である。その彼が、Ioke(リンク)というJVMの上で動く新しい言語を開発している。Iokeの型を重視し、非常に動的でプロトタイプベースのオブジェクト指向言語が目指すところは、素晴らしいぐらい小さい正規構文を持つLispやRubyを使用したときに得られる同等の力を開発者に授けることである。
Ola氏は、以下にIokeの本質(リンク)に関する説明をしている。
Iokeは、強力な型付け言語であり、動的、プロトタイプベースのオブジェクト指向言語です。それは同図像であり、数種類のマクロがビルトインされています。Iokeに最も影響を与えた言語は、Io(リンク)、Smalltalk(リンク)、Self(リンク)、Ruby(リンク) そしてLisp(リンク) (厳密に言うとCommon Lisp(リンク))です。
Iokeは、現時点でJVM上で構築されていますが、IokeをコンパイルしてJavaScriptに変換し、変換したコードをV8で動かすことも現在考えています。
私は言語に関していくつか目標をもっており、そのなかでももっとも具体的な目標は、私がRubyやLispで好きな点を取り入れた言語を作ることです。Ioには既に自分が求めている機能が沢山あることは分かっていますが、ある場面で、十分でないなと思うことがあります。また同様に内部DSLを表すのに非常に適した言語を欲しいとも思っています。自分の邪魔をせず、望んでいることを成し遂げるのに必要な力を沢山与えてくれる言語が欲しいと思っています。そのような成り行きで、私はマクロシステムを設計しました。私が設計したものに対して、おそらく正気でないと思う人もいることでしょう。
InfoQは、Ola Bini氏にIokeの言語デザインに関して、質問をいくつか行った。
InfoQ: Iokeの目玉機能の一つはプロトタイプベースの継承を使っていることだと思いますが、優勢なクラスベース指向と比較し、プロトタイプベースの継承を使用している利点は絶大だと思いますか?
仰るとおりプロトタイプベースの継承はIokeの目玉機能の一つですが、それが目玉機能かどうかは自分では確信していません。いくつかのデザインを大幅に変更したといえば、確かにその通りです。クラスベースのシステムと比較して、プロトタイプベースの継承に対し実際のところ快適さを感じています。そしてIokeは、そもそも自分のために開発した言語なので、自分の快適さを大切にしがちです。
Rubyでは、シングルトンクラスを使い、プロトタイプベースのオブジェクト指向に少しにていることを成し遂げることが出来ます。あなたが凄く手際よくアルゴリズムを組み立てることが出来ることが分かります。そして言語が持つ力にはっきりとした問題なんかありません。望めば、いつも規約に従ったクラスベースのオブジェクト指向を行うことが出来ます。
Iokeの主要な指針となる方針の一つは、どんな決定も当然と考えたくないことです。単にクラスベースのオブジェクト指向が、有力なパラダイムというだけの理由で私はそれを使うべきでしょうか?いや、そんな必要はありません。多くのことに対して、明らかに相応しい理由があるが、同様に障害も沢山あります。ほとんどのアプリケーションに対して意味をなさない歴史的な障害も沢山あります。だから私は、Iokeを開発中の間は出来るだけ多く通うよう努めています。
InfoQ: プロトタイプベースの継承を持つ唯一の主要言語は、JavaScriptなので、この実例は、広く理解されそして使われると可能性があると思いますか?
実際のところ、プロトタイプベースオブジェクト指向は、クラスベースオブジェクト指向よりも自然で理解するのは簡単だと思います。クラスベースオブジェクト指向は、学ぶ必要があると思います。そして一旦クラスベースオブジェクト指向のマントラを捨てたら、ほとんどの人は、クラスベースオブジェクト指向よりもプロトタイプオブジェクト指向の方が分かりやすいと思うでしょう。もちろん、JavaScriptは、比較対象としてベストではありません。言語モデルの粗雑な隅にJavaScriptのプロトタイプベースとしての本質が隠れてしまうからです。そのことは、ほとんどの開発者は実際のところ、JavaScriptのプロトタイプとしての使い方を知らないことを意味します。
InfoQ: Iokeは、ゼロからデザインして、JVM言語になっているようですが、このことは、新しい言語が主流になる優位な傾向になると思いますか?
自分自身のバーチャルマシンをゼロから作ることは全く意味がないと現在私は考えています。新しい言語のほとんどは、ガベージコレクションを利用します。しかし、私が理解出来ないのは何故言語を作る人は、自分自身のガベージコレクションを書きたがるのかということです。GCが完成するまでに数ヶ月かかり、そして出来上がった後も、一般的に平均以下の能力しか出ません。RubyがGC周りで抱えているトラブルを見てください。明らかに、この私の考えは、他の多くのことでも、特にライブラリに関しては意味がないと言えます。だから、Iokeは、JVM言語なのです。しかし、ほとんどの言語は、JVMに依存していません。Iokeを他のプラットフォーム上で、非常に簡単に再実装出来ます。コアはとても小さいからです。JVM、CLR、Parrott、そしてかなりな程度で、LLVMを対象とする言語は、模範であるべきだと思います。ゼロから自身のVMを作る意味がある場合はほとんどありません。
InfoQ: Iokeで実装した状態処理は、Javaにおける例外処理に似ているが、より柔軟に思えます。状態処理が重要であることを示す例を教えてくれませんか?
例外は、状態処理機能のサブセットを提供していると言うかもしれません。違いが二つあります。一つはプロトコルと抽象化の違いです。例外処理が使われている箇所全てが例外やエラーである必要はありません。または警告に関しても同様に、ほとんどの動的言語には、特別なログベースの警告処理があります。しかし他のことをしたい場合はどうしますか?Rubyでは、warnメソッドを変更し例外を発生することが出来ます。しかし、このことは警告と例外をどのように扱えば良いかという点において分裂があることを依然として意味します。処理の割り込みやスレッド割り込みを例としてとりあげてみましょう。これらの全ては、一見異なる機能ですが実際は同じものに見えます。
状態処理によって、これらを一つにまとめることが出来ます。状態処理は、これらの種類のイベントをやり取り出来る同一のプロトコルを提供してくれます。
あなたが状態処理から受ける機能性は、二つあります。ひとつはリスタートであり、それは実際のところほとんど完全に分かれています。
リスタートは、ブロックに登録することが出来ます。リスタートが起動されると実行できるコードです。名前付きリスタートを起動するメソッドがあります。全てのアクティブなリスタートなどを見つけます。Restartは、ほとんど例外処理の仕組みで、ほとんどが直接スコープします。
状態処理によって起こりえる事に対するハンドラを登録出来ます。状態が起こったら、ハンドラは、自分自身でハンドリングするか、又は次のハンドラへ処理を渡すか選択することが出来ます。しかし、これはスタック構造というわけではありません。もしハンドラが状態に関して何かを行いたい場合、(ハンドラもまたコードの一つです)、そのコードは、ハンドラのレキシカルコンテキスト内では実行されるが、状態が最初にシグナルされた動的スコープ内では実行されないでしょう。このことは、状態のシグナルを発するポイントからのいくつかのハンドラメソッドのコールが、コンテクスト内で実際に事を行っていることを意味します。
このことは変ではありません。例えばPure Ruby内でそれを実行出来ます。もしそれが標準ライブラリで利用可能でないのであれば、最大限の力を発揮できません。
Common Lispでは、それはとてもパワフルです。Common Lispをインタラクティブに使用した場合、デフォルトの状態ハンドリングは、デバッグを必要とします。このデバッガは、エラーが起きたコンテクスト内で起動します。そして、新しい値を変数に設定するということを含めて、ハンドラと同じ事が出来ます。デバッガは特別なことを全くする必要がなく、それは、状態システムにとって本当に特別な使い方にすぎません。
私は、これがどれぐらいパワフルであるかを強調することが出来ません。
InfoQ: Iokeは、メンテナンスとリファクタリングに関してどのように基準に達し、そして動的でまた強い型付けなのでしょうか?
この点に関しては言い辛いところがあります。Iokeは、全く簡潔で尚かつ強力な機能を簡潔に提供するので、維持可能でなくてはいけません。自動化されたリファクタリングは、この点に関して同様の理由で恐らく興味がありません。
ちょうどLispのように、Iokeは、構文上の抽象概念を提供します。それらは、二つの形をとります。ひとつはマクロであり、それは基本的に特別な方法で評価可能な遅延引数を持ったメソッドコールに似ています。もうひとつのフォームは、シンタックスであり、それは、Common Lispのdefmacroと似た働きをします。これらは、一緒に新しい制御構造を作成する実現性を提供し、新しい抽象概念を定義します。例えば独自のメソッドタイプを作れるほど言語はパワフルです。もしキーワード引数が嫌いなら、キーワード引数でないメソッドタイプを新規に定義出来ます。IokeのDefaultMethodは、現在のところ純粋にマクロを使用してIokeで実装可能です。
InfoQ: Iokeの構文に対して、あなたはLispとSmalltalkの例に従うことを選びました。例えば、スペースを使うことです。このことによって、Cのようなコードを読み書きするのに慣れている開発者は離れるのではないかと言う人もいますが、正しいと思いますか?
私は、長年C、C++、Javaプログラマでしたが、決してそれらに対して満足出来ませんでした。それは本当に扱いにくいシンタックスです。そして、私よりも前に多くの人が、それが実は強力な抽象概念に対して重要な障害である点を指摘してきました。それらの言語に似ている抽象構文木を持つとき、構文上のマクロを実行するのは、とても不便です。それが非常に不均一なので、構文はその点に関して大部分を占めています。
だから、最初Iokeは不自然だと思う人がいるのでしょうが、それが読み込む方法が私は本当に好きで、そしてこの点に関して同様に好きになる人がいるだろうと思います。Iokeは、Javaとは異なり非常に可読性が高いです。読むのに邪魔になる句読点が多くないです。Java、RubyそしてIokeを比較してみましょう。
Arrays.asList("foo", "bar", "quux") .map(new Function>(){ public Pair call(String str){ return new Pair(str, str.length()); }}).select ..... // これは長過ぎますよね? ["foo", "bar", "quux"].map {|str| [str, str.length]}.select {|n| n[1] > 3} ["foo", "bar", "quux"] map(str, [str, str length]) select(second > 3)Rubyとの違いはこの場合そんなに大きくありませんが、物凄く異なる書き方も出来ます。空白文字で区切られたメソッドを読むのは、はるかに簡単だということが分かりました。ドットを使い式を区切るのも同様に重要です。
従って、Lispを使う者として、このように言うのは異説を唱えるような感じが若干しますが、構文は実際のところ重要です。私がIokeで目指しているものは、私がLispやRubyから得たのと同様な力を手に入れることですが、Iokeを素晴らしくそして小さい正規構文と結合することです。
Iokeの開発に興味があるなら、Ola氏のgitリポジトリ(リンク)からIokeをチェックアウトが出来るし、プロジェクトのページ(リンク)を見ることも可能だ。
Iokeに関して、InfoQのプログラミング言語(参考記事)、JVM(参考記事) やRuby(参考記事)のページでより多くの情報を収集出来る。