BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース X++ プログラム言語の概要

X++ プログラム言語の概要

ブックマーク

原文(投稿日:2011/08/08)へのリンク

X++ は Java のデータアクセス機能を強化したスーパーセットとして設計された。例えば X++ では,insert_recordsetupdate_recordsetdelete_from などのキーワードによるセットベースのデータ操作がサポートされていて,それぞれ SQL の Insert,Update,Delete 文にマップされる。一般的にはこれが最高のパフォーマンスを得られる方法だが,セットベースのアクセスと命令型の文を組み合わせたハイブリッドなアプローチを選択することもできる。

上のコードにある "myTable.AmountMST += 100;" という文が実際にはセットベースの操作で,後に続く where 句で選択されるすべてのレコードを操作する。

もうひとつの違いとして,X++ は LINQ のような ORM で生成されるプロキシオブジェクトへの依存を持たず,コンパイル時に実際にデータベースのメタデータへのアクセスを行う,という点がある。これによって,C# や VB よりもはるかに厳格な静的チェックが可能となっている。それがどのように実現されているのか,説明を続ける前に少し見ておこう。

多くの組み込み言語がそうであるように,X++ も当初は完全に独自のスタックを持っていた。IDE,コンパイラ,pコード形式,インタプリタなどは IBM Axapta のものを使用した。この製品は後に Microsoft Dynamics AX となった。X++ はほとんどの期間において Axapta の特定のインストール用に記述されてきたため,コンパイラをデータベースに直接結びつけることが可能だった。つまり Customers テーブルクラスへのアクセスが,文字通り Custmers テーブルへのアクセスとなるのだ。

Dynamics AX 2009 以降の X++ では,.NET スタック上に構築された第2のコンパイラが用意されている。このことがいくつかの興味深い問題を引き起こした。X++ では旧バージョンの Visual Basic のような,確定的ガベージコレクション(deterministic garbage collection)を使用していた。このガベージコレクタは残念なことに,50万以上の有効なオブジェクトが存在する場合において,深刻なパフォーマンス上の問題を抱えていた。ガベージコレクタをスクラッチから書き直す,というアイデアを諦めた彼らは,代わりとして .NET のガベージコレクタを活用することを決めた。

独自のランタイムから .NET への移行は,それ自体がひとつの挑戦だった。X++ チームは非常に小さく,コンパイラをエンド・ツー・エンドで書き換えるだけの資金を調達できるるとはとても考えられなかった。そこで彼らは,pコードのレベルから始めることとした。使用するコンパイラは同じだが,pコードを解釈する代わりに,それを IL コードに変換するツールを実行するのだ。pコードと IL はともにスタックベースの言語なので,変換は驚くほど簡単だった。

X++ はこの確定的ガベージコレクションだけでなく,ユニークなクライアント・サーバ機能も失っている。DCOM や .NET リモ―ティングのように,X++ のオブジェクトはサーバとクライアントで同時に活動することができる。このようなクラスのメソッドコールはすべて,ネットワークを越えて実行される。これによって可能になるアーキテクチャ設計には興味深いものがあるが,一方でこの話し好きでステートフルな設計は,残念ながら拡張性の面で不十分であったため,X++ チームはこれを廃止したいとずっと考えていたのだ。

いくつかの部分では,X++ は Java よりも型安全性が低い。例えば "if" 文の条件式は Boolean 以外でもよく,非0の整数値や非nullオブジェクトが真と評価される。また代入演算子("=")は,データ損失が発生する場合でも,暗黙的な変換の実行を試みる。さらに AX 2012 以前については,基本型から派生型へのキャストも暗黙的に行われる。

文字列の扱い方にも違いがある。 X++ の文字列は単一あるいは二重のどちらの引用符で区切られていてもよく,比較時には大小文字が区別されない。X++ には char データ型がないが,長さ1の固定長文字列を宣言することができる。またほとんどのC言語ベースの言語と同じく,X++ も結合用の追加オペレータを採用するという誤りを犯している。文字列リテラルのエスケープシーケンスにはバックスラッシュ(\)を使用するが,C# と同じようにアットマーク(@)が先頭にある場合は除外される。

X++ では,ローカル変数はメソッドの先頭で宣言しなければならない。ループ変数にもこれが適用されるので,Cベースの他の言語とはシンタックスにわずかな違いが生じている。while 文には違いがなく,continue や break もサポートされている。

X++ の switch 文では,case に複数の値あるいは式を記述することができる。それぞれの定数値あるいは式はカンマで区切られる。ただし範囲指定 (case is > 5 のような) はサポートされないので,パワーカーブ的には VB と C# の間に位置することになる。

X++ には列挙子とイテレータの両方がある。X++ のイテレータは Java のものと同じように,コレクションのナビゲートを行うだけではなく,実行中の項目追加および削除が可能である。列挙子の方は .NET の IEnumerator と同じく読み取り専用のビューであり,コレクションが変更された場合には処理が失敗する。

エラー処理は基本的に Java や C# の構造化例外処理に基いているが,3つの大きな違いがある。X++ の例外は数値エラーコードそのものであるため,前述の言語のように多くの情報を保持することはできない。また X++ には retry 文というものがある。これは,もっとも内側の try ブロックの先頭にジャンプするという,事実上 goto 文の機能を持つもので,デッドロックのような断続的エラーを扱う場合に非常に有効だ。さらに,X++ は finally ブロックをサポートしていない。確定的ガベージコレクションがなくなったことを考えると,これは問題があるかも知れない。

X++ は継承とメソッドオーバーライドをサポートするが,オーバーロードはサポートしていない。オーバーロードをシミュレートするためには,オプションパラメータを使用する必要がある。メソッドは Java と同じくデフォルトでは virtual だが,"final" キーワードを使用してシールすることもできる。

この記事に星をつける

おすすめ度
スタイル

BT