Cristian Vlasceanu氏は、Dコンパイラの.NETプラットフォームへの移植を行っている。
Dのことをまだ知らない読者のために、Dについて説明してもらえますか?
Dはマルチパラダイムな言語です。オブジェクト指向をサポートし、関数型やテンプレートによるメタプログラミングが可能です。また、gotoやインラインアセンブラといった実用的な機能も兼ね備えています。
Walter Bright氏(Dの父)は、Dは(言語設計者ではなく)コンパイラの実装者によって考えられた言語だと説明しています。確かにそうかもしれませんし、いくつかのもっとも成功したソフトウェアプロジェクトにおいて作者らからいくらか要望が出ているのも確かです。とはいえ、Walter氏の説明はDを安売りしかねません。彼は間違いなくユーザのことを考慮して設計しているし、ただ文法が実装時に解析しやすいだけではありませんから。
多くの点で、Dは「正しい」振る舞いを促します。たとえば、CやC++では、"int i;" と書いてもその変数は初期化されません。「正しいこと」をさせるには、プログラマは "int i = 0;" というように余分にキーを打つ必要があります。しかしDでは別の方法を取ります。"int i;" と書けば安全にデフォルト値がセットされます(この場合はゼロ)。初期化しないようにする場合はより多くの努力を要します。 "int i = void;" と書くことで、意図的に初期化していない変数であり怠惰なためではないことを表現するのです。
最初にDコンパイラを書き始めようと決断した理由は何ですか?
このプロジェクトはコンパイラのバックエンドを書くことだけです。フロントエンドはWalter氏のコンパイラをベースにしています。彼はオープンソースで利用できるようにしています。私はできるだけフロントエンドを変えないようにしています。
私はこれまでの経歴の中でインタープリタのフロントエンドを扱う機会を持ってきましたが、コード生成の経験は限られていました。またほとんどの仕事でC++ を使っていたため、NET(そしてC#)詳しく知ったのは最近のことです。.NETコードジェネレータのプロジェクトはそれらを学ぶ絶好の機会でした。これが第一の理由です。
別の理由としては、.NETのためのコンパイラの実装が(ただのプロトタイプだとしても)重要な、成熟したコンピューティングの基盤をDコミュニティに提供できることです。.NETがサポートする他の言語との間への痛みのないやりとりの道が開けたのです。
私は、Dコミュニティの一部が主張する性能に関するネイティブコードの利点について(サンプリングした)の証拠を持っています。コンパイラの実装がなければ、ネイティブコードの根拠のない利点を立証することも反証することもできません。
このプロジェクトを研究目的にするか、製品用途にするかといった考えはお持ちですか?
これは研究プロジェクトです。私はDコミュニティからどんな反響が出るか予想できません(数週間以内にコードをリリースする予定なので、そうすればわかるでしょう)。また、この時間外のプロジェクトに私がどれだけ関われるかもわかりません。このプロジェクトが時間をかけて成長し、製品用途の品質にまで達することを期待しています。しかし今の段階では先駆的といった段階です。
あなたはブログ「Programming and Debugging (in my Underhøøsen) (リンク)」の記事で、コンパイラを作る際の互換性のたくさんの問題について取り上げていますね。それらの互換性の問題の中で、一番興味をひく、もしくは難しいと思うものは何ですか?
これは断然、部分配列が有名な悩みの種です。もうこれはおなじみのアレといった感じです。Dの持つ機能で、"x"という整数の配列があるとき"int[] y = x[2..5];"と書くことで、"y"は"x"の2番目の要素から5番目の要素(これは含みませんが)までのビューとするものがあります。"y"は一連の要素のコピーというよりは、軽量なオブジェクトの一種です。.NET では同じような概念のArraySegmentがあります。ArraySegment(これは値型です)は配列とははっきりと異なる型です。
D は配列と部分配列を区別しません。"foo(int [])"というシグネチャの関数があれば、配列と部分配列のどちらも入力できます。私は、これはプログラマにとってはわかりにくく、コンパイラのコードジェネレータに正しく理解させるのも大変難しいものだと思います。私の現在の解決法は効率的ではありません。というのも、配列から ArraySegmentへの隠れた変換、またその逆をたくさん必要とするからです。私はWalter氏を説得してD 2.0では部分配列を独自の異なる型にするよう説得したいと考えています。配列とそのビューは異なる概念であり、そのようにモデル化すべきなのです。
しかしその他では、Dと.NET(とC#)の間で同様のものを多く見つけられたので、スムーズに進みました。
Dの機能でCLRやC#に実装したいと思うものは何ですか?
D に「クラス不変条件(class invariant)」と呼ばれる機能があります。これは"invariant"という予約語のメソッドを書くことで利用できます。コンパイラはこのメソッドをコンストラクタの呼び出し後、publicメソッドの呼び出し前後、デストラクタの呼び出し前に呼ぶようにコードを生成します。メソッドの本体は主に一連のassert文でできていますが、健全性を検査するコードなら何でもここに入れることができます。これはデバッグにとてもとても便利です。私はこれと同様のものがC#にあってもいいと思います。と言っても私はほとんどC++な人ですけどね。
Code Contracts(参考記事)の機能にあるオブジェクト不変条件のようですね。
そうです、同じ理念のものです。しかし少し違いがあります(私がドキュメントを正しく読んでいればですが)。Dはリフレクションや(ccrewriteユーティリティのような)外部ツールを必要としません。契約プログラミングは「一級市民」な言語パラダイムなのです。たぶん私はそのライブラリの利便性を完全には評価できていないのでしょうが、それでも相当な複雑さを感じてしまいます。Dのやり方はよりスリムで理解しやすいものだと思います。
しばらくの間この仕事をされてきましたが、コンパイラ開発のプラットフォームとしてCLRはまだ気に入っていますか?
CLRは知れば知るほど、評価が高くなっています。CLRはそのグロテスクなvtableレイアウトやスタックの巻き戻しといったことよりはむしろ、言語機能に焦点を合わせるのに使いやすいと感じています。
動的言語ランタイム(DLR)について興味はお持ちですか?一般的にでもDに関してでもかまいません。
いい質問です。PythonやRubyと違い、Dは静的型付けです。私の最初の直感ではDLRはこのプロジェクトには必要ないものだと思いました。しかしちょっと見ただけですが、先に挙げた部分配列の難問にDLRが役に立つのではないかと思っています。