いつもの妄想ってかんじで、、、C言語置換言語の要件

参考→http://d.hatena.ne.jp/h_sakurai/20090720#p3

私の妄想を書いておきます。

1. アセンブラ親和性が良い

今のC言語は、外部シンボルに_が付いたり@が付いたり、それがコンパイラごとに違っていてアセンブラから見たときの扱いが、最悪とは言いませんが結構酷い。
FreePascalのalias指令のように、外部シンボル名を完全にコントロールする機能が必要。register記憶クラスを拡張して、引数を渡すレジスタを指定できればなおよし。Adaの内部表現指定機能みたいなのも必須。
また、今のC言語同様に、可能な限りCPU命令にある機能は直接使い、無駄にランタイムを要求しない。これを崩してしまうと使い物にならない中途半端なものになるでしょう。
あと、いまだに外部シンボルがオブジェクトファイル間でグローバルなのはどうにかする必要あり。まず名前空間を扱えるアセンブラを作ってから、それと親和性の高いモジュール機能を入れる。

1-1. GCを含まない

GCはランタイムが必要なので、1の要件により言語には組み込まない。
オプショナルにすることも考えられますが、その場合は(保守的GC以外だと)結局コンパイラがヒントとなる情報を吐く必要があり、その情報の形式によって色々固定されてしまう。
だからGCは一切考慮しない。必要なら特定の実装が独自拡張として持てば良いでしょう。

1-2. OOP支援機能を含まない

VMTのレイアウトを固定してしまうため。

1-3. 抽象データ型

こちらは必要。モジュール外からは箱としてしか扱えないような宣言ができればなんでもいいわけですが、資産利用を考えると、結局、構文としてはC++のclassがいいでしょうね。virtual禁止で。
COMを使える言語が結構多いことを考えると、関数ポインタをグループ化したものとしてのCOM互換のinterfaceは有りかもしれない。
抽象データ型を入れるなら、placement newも必要。というより「メモリマネージャを言語に含めない」要求により、mallocした後placement newで初期化の(Objective-Cみたいな)2段構えになるはず。

2. 簡単に他言語のインポートライブラリを書ける

C言語の.hが複雑怪奇なために、世界中で大勢が困っています。
自動とまでは言わなくても、少なくともDのようなある程度似た言語には単純置換に近い形で持って行きたい。

2-1. 外から見える箇所の記述にはマクロは全面禁止

2の要件により、必須事項。
今の.hでも、cppを通した後のものを他言語に置換することは簡単にできますが、展開前のマクロが付いてこないと使い物にならないことが多いです。定数にもインライン関数にもtemplateにも名前変形にも条件コンパイルにも使えてしまう#defineの万能性が全て悪い。テキストベースのマクロでこれだけ困っているのに、LISPのような高度なマクロは問題外と言えましょう。「展開前のマクロ」がAPIの一部にされてしまうのが目に見えています。
要件1でモジュール機能を入れる事になっているため、#includeも廃止。
また#ifdefが多用されるのも、現在のC言語コンパイラごとの拡張に頼らないとできないことが多いのが原因。要件1で外部シンボルや内部表現を完全にコントロールできることになっているため、そちらで吸収。どうしてもの場合はプラットフォーム別にソースを分けるなどする。モジュール機能があればmakeよりマシなビルドシステムも作れるため、たいして困らないはず。

2-2. template

多相型用途の#defineの使い方が現実に存在する以上、マクロを禁止するなら必要。
凶悪なテンプレートライブラリは他言語に持って行けなくなりますが、簡単なものなら、genericや多相型のある言語なら対応取れますし。

2-3. C言語資産を使える

使えないとC言語置換言語として話にならない……が、要件2とも矛盾しないようにする必要あり。
そのため、モジュールの実装部というかprivate部ではマクロを解禁して、#include も可能にする。「展開前のマクロ」も使えないといけないので、構文はC言語上位互換。

3. 他の言語で一般的になってきた機能を上記要件に反しない範囲である程度サポートする

C言語置換言語を使う側も、インポートライブラリ作る側も嬉しいため。

3-1. downward closure

gccのトランポリン方式は、スタックを実行できないCPUで死ねるので、D言語の、コードアドレスとスタックフレームを組で持つ形が良い。
関数外に持ち出せる真のクロージャも、Delphiのように参照カウント方式で実装できますが、メモリマネージャが必要なため無しで。

3-2. ビット集合型

要するにPascalのset。
C言語置換言語側で区別していると、enum相当の型でand/or演算ができない言語に持って行くときに区別がついて嬉しい。

3-3. 構造化例外処理

オブジェクトファイルレベルで構造化例外処理がサポートされてきたため、必要。
自前で例外を投げる機能はライブラリでも良いが、呼び出し先で例外投げられても後始末ができるように、構文としてfinallyは必須。

3-4. ベクトル演算

Fortranにあるようなやつ。いやFortranよく知りませんが。サポートしているCPUが増えてきたため、必要。

3-5. D言語の配列の構文

全部右から左に読めば良くなるのでだいぶ違います。
正直宣言の構文全部作り直せとは思いますが、.hを#includeできなければならない都合とkiss原則によりなるべく変えない方向で。

3-6. 演算子の優先順位をまともにしたいが.hを#include(ry

ダメだこりゃ。

3-7. デフォルトでfall throughしないswitch文

fall throughさせたいときはgotoでも書けばいいし。

3-8. 多重break、ループ以外の単なるブロックからのbreak

まあgotoと同じなわけですが、原理主義者を多少回避できるのは(ry

3-9. Eiffelのretry

まあgotoと同じなわけですが、原理主義者を多少回避できるのは(ry

結論

イメージとしては、GCとclassを抜いて、private節限定でプリプロセッサを解禁したD言語
私自身は……欲しくないな(ダメじゃん