OSCON で、最近の Emerging Languages Camp( 1日目 と 2日目)は、新しい言語についての講演の長いリストが特徴となっている。ほんの2,3週間前にできた実験的なものからGoogle Go や Newspeak のようなもっと成熟したもの、そしてDのように紛れもなく古顔なものまで、様々な開発段階のものがある。
JRubyの Charles Nutter氏は、Rubyのシンタックスが好きな人に受けそうな Mirahという言語を発表した。
InfoQは、Charles Nutter氏に、これまでのJRubyや他のJVMベースの言語との違いについて尋ねた。
InfoQ: 以前は公式に、Dubyと言う名前で、知られていたMirahですが、誰向きですか?
現在のところ、Mirahは、「Javaを書く、もっと良いやり方」と表現するのが一番いいようです。そこで、一番のターゲットは、今現在は、javacをもっといいシンタックスと、いくつかの追加のフィーチャで、置き換えたいと願っているJava開発者ですね。
InfoQ: Mirahは、全てのプログラマが移行できる/すべき言語ですか? それともある特定の領域を狙ったものですか?
ゴールは、Javaができることは、すべてでき、Rubyができることもいくつかでき、なおもできるだけ軽量である(すなわち、ランタイム ライブラリを必要としない)言語を作ることです。なので、Javaが使えるところならどこででも、Mirahが使えるべきです。JavaのライブラリやほとんどのJavaの型システムは、その周りに少々のシュガーを配置すれば、本当は重荷となるものではない、わかりました。私にとって、入手できる最高のシュガーは、RubyのシンタックスとRubyの「明らかな」言語フィーチャから得られます。我々は、シンタックスとしてRubyから始めて、JavaすなわちJVMバイトコードが結果です。この方法がどこまで続けられるか、確認します。
InfoQ: MirahとMirahコードは、どうやって使うのですか? コンパイラーかインタプリタがありますか?
Mirahは、静的に型づけされ、コンパイルされる言語ですが、スクリプトでも充分動きます。ほとんど「いくつかの型アノテーションをもったRuby」を書いて、それからスクリプトとして走らせるために"mirah" コマンドを使うか、 "mirahc"コマンドを使ってコンパイルし、JVMバイトコードかJavaのソースに変換します。両方のコマンド共、 "-e"フラグで、即コマンドラインからスクリプト実行ができます。
InfoQ: 一度、コードがJVMバイトコードにコンパイルされたら、ランタイムのどれだけが引きづられるのですか?
(動的呼び出しのサポート以外、)言語フィーチャは、あなたが直接、自分で参照するクラス以外に、いかなるライブラリ依存性も、課しません。できるだけ長い間、言語特有のランタイムを避けるのが、言語の第一の設計目標です。そうすることを永久には、できないかもしれませんが、目指すのはいいことです。他のJVM言語は、あなたが一行でもコードを書けば、ランタイムをいっしょに出荷する必要があります。Mirahでは、ソースを入力して、実行コードを出力します。あなたはそれをリリースします。実際的です。
InfoQ: Mirahのバイナリは、Android用のDexコードに変換されるのに都合がいいですか?
その通り! Android SDKは、どんなJVMバイトコードでも Dalvik用のバイトコードに変換しますので、MirahをJVMバイトコードにコンパイルするか、Javaのソースにコンパイルしてから、javacを使ってコンパイルします。一度Mirahコードをコンパイルしてしまえば、(JVMやJVM関連のツールにとっては)どのjavacで生成したものか、基本的に見分けがつきません。
InfoQ: Mirahは、JRubyにとって、 Squeakの Slangみたいなものになるのですか?すなわち、動的言語の制限付きのサブセットで、早いコードに簡単にコンパイルできる?
それがMirahを作る最初の理由の一つでした。ある時点でそうなるでしょう。JRubyの拡張(あるいは、JRuby自身)をMirahで書くことは、Javaのシンタックスを望まない開発者には、ずっと訴えやすいですね。しかし、現時点では、我々は、Mirah自身をもっと安定させることと、抜けているフィーチャを作り上げることに専念しています。
InfoQ: Mirahは、Mirahで書かれているのですか(あるいは、ある時点でそうなりますか)?
今は、Antタスク用のツールのような、Mirahの小さな部分は、Mirahで書かれています。セルフホストされるように、移行したいですが、それは、現在の第一の目標ではありません。Mirahのコードベースは、現在ほとんどすべてRubyで書かれていますが、Rubyは、コンパイラ(とランタイム)を作るのに本当にいい言語とわかりました。セルホストは、我々に太鼓判を押してくれることになるでしょう。しかし、Rubyのツールチェーンよりもずっといい改善がなければ、おそらく、すぐには、セルホストは、できません。
もちろん、もしJRubyがMirahで書きなおされたなら、その時は、セルフホストするでしょう、MirahがJRubyをブートストラップし、JRubyがMirahをブートストラップするようなやり方で、ですね。
InfoQ: MirahとRubyの差は、なんですか? RubyからMirahを作るのに加えたものと除いたものは、言語や文法の点から見ると何ですか?
最初、我々は、コンパイルするファイルの基本構造:クラス、メソッド、インスタンス変数、リテラル、インポートを作ることにのみ焦点を当てていました。進むにつれて、interfaceのようなJava特有のフィーチャ、そして、内部イテレーション(Java5のforループようにコンパイルされる)とクロージャー(Javaの匿名内部クラスのようにコンパイルされる)のようなRuby特有のフィーチャを加えました。我々は、両方の言語からのフィーチャを加え続けます。そしておそらく、(Scalaから)暗黙の変換、あるいは、( Clojure かsephから)明示的なイミュータブル クラスのような、いくつかほかのものを借りる事を始めます。コンパイラだけで、ランタイム ライブラリ無しに、どの程度やれるのか、確認するのは、興味の沸くことです。
InfoQ: 他のMirah(Duby)のバックエンド、例えば.NET用の開発がありましたよね。
はい、Jimmy [Schementi] 氏がC#のソースを出力できるDubyのバックエンドのプロトタイプを開発してました。単純なフロー制御、基本的な数学、そして基本的なリテラルを扱うのには充分なほどうまく動いていた、と思います。開発が再開して欲しいです。
InfoQ: 他のバックエンドもあるのですか?(ネイティブ、あるいは、LLVM; Rubinius)?
Cバックエンドで実験しましたが、Rubyシンタックスの性質から、ターゲットのバックエンドは、おそらくオブジェクト指向であり、ガ-ベッジコレクションがあり、そして構造的にRubyかJavaに、似たものでしょう。例えば、GoバックエンドとかOOCバックエンドは、うまくいくでしょう。
Mirahは、またRuby自身のような動的言語のランタイムをターゲットにできるでしょう、究極的には、コンパイル時にそれらのバックエンドに静的に型安全性をもたらすことになるでしょう。私は、実際に、それがどのようなものになるか、あるいは、それらのシステムの動的な性質(例えば、実行時の可変な型)によって、それらの上に静的な言語を作ろうとする試みが失敗するのかどうか、考えていません。
InfoQ:どのようにしてMirahは、JVMと結びつくのですか?-あるいは、もしそうでないなら:どうやってMirahをJVMに依存しないようできるのですか?例えば、開発者は、どの型を使うのですか?例えば、'fixnum'が型のアノテーションとしてあります。-どうやってそれは、定義されるのですか?
使われる型名は、ほとんど推論とコード生成段階で定義され、そしてターゲットのバックエンドに、適切なものにマップできます。初期のMirahのコードでは、"fixnum" は、単に"int" や"long"の別名として使われていました。最近では、一般的にJVMをターゲットにしているMirahコードは、型として直接、単に"int" や"long"を使っています。他のすべての型は、JVMプリミティブ("float", "double"など)、通常のJDKクラスあるいは、サードパーティのライブラリです。Mirah プログラムを無修正で、違うバックエンド上で動かすことは、期待できません;それは、言語の目標ではありません。しかし、もしあなたが、あるバックエンドのMirahを知っていれば、別のバックエンド用に書き直すのは、簡単です。言語の見かけのフィーチャは、同じだからです。
InfoQ: コミュニティは、どうですか?誰が協力者ですか?
今は、コンパイラの開発は、ほとんどGoogleの Ryan Brown氏がやっています。私がやれるときは、私も開発しています。他に数人がパッチを当てたり、フィーチャを加えていますが、今日でも、かなり若いプロジェクトです。
InfoQ: あなたが名前を挙げたい協力者によるプロジェクトや記事なんかありますか?
Phil Hagelberg氏によるGarrettと呼ばれる「Android開発のための遊び場」があります: http://github.com/technomancy/Garrett
"consiliens"の名で通っている他の協力者は、GWTアプリケーションを生成するMirahのパッチを開発しています。これは、非常に面白いですね。というのは、GWTは、Javaの「ソース」だけを処理するので、基本的には、他のたいていのJVM言語でGWTアプリケーションを作る方法が無いからです。
Googleの John Woodell氏もDubiousという名のwebフレームワークの基礎をまとめています:http://github.com/mirah/dubious。彼は、Mirahと同じような設計アプローチをとっていて、Rails風の構造から始めて、それをMirahコードとしてコンパイルするのに必要な空白だけを埋めています。Dubiousは、自分のアプリケーションやライブラリが、言語に従うことを強制するのではなく、自分のアプリケーションやライブラリの周りに言語を作り上げる例です。簡単に理解できるコンパイラと柔軟なシンタックスによって、Mirahでそれが可能になるのです。
InfoQ:Mirahで数値は、どうですか? 数値の型階層、オーバフローできる固定サイズの値、ボクシングなどありますか?
JVMをターゲットにしている時、数値の型階層は、JVMのままでした。プリミティブな数値の型とそれらのボックスされた等価のものです。オーバーフローもJavaを書いている時とまったく同じように振舞います。
InfoQ:タグ付きの数や immediate types (即時型)に対するJVMのサポートは、役立ちますか?
Javaに役立つのと同じようにMirahにも役立ちます。それで、ボックスされた数を、作ったり、使うコストは、かなり小さいです。そのほかには、タグ付きの数に対する差し迫った必要性は、ありません。MirahもJavaのプリミティブ型をサポートするからです。
InfoQ: メタプログラミングのフィーチャについては、どうですか?
メタプログラミングは、第一にコンパイル時にマクロの形になります。これは、Mirahの見かけのフィーチャのいくつが実装されたものです。例えば、クロージャーは、コンパイラによって、それと等価な匿名の内部クラスの形に変換されます。コンパイラをRubyで書くことによって、言語があなたの要求に合うように設計できますし、このような変換をするマクロを生成するのが非常に簡単になります。
私は、またMirahがもうちょっとRubyのように感じられるようにする、2つの主要なフィーチャを加えたいと思います:オープンクラス、これは、C#の拡張メソッドのようにコンパイルされます、そして暗黙の型変換、これは、Scalaのものとかなり同じように振舞います。これら2つの単純なフィーチャによって、静的に型付けされる言語が、ずっと動的に型付けされる感じになるのです。そして両方のフィーチャが、ランタイム ライブラリを一緒に出荷せずにサポートできるのです。
Mirahのソースコードは、GitHubで入手できる。