言語作りといってもそれほど大げさな話ではないというような話をしました。「ちょっと凝った設定ファイル」とか「ちょっと凝ったライブラリ」というような流れがあるということも話しました。具体例を挙げて紹介します。何かプログラムを作る際、まずはライブラリを整備してからプログラムを作ることが多々あります。元言語の文法の制約を越えたいと思うことがときどきあります。時には、マクロやプリプロセスを使って無理やり言語の制約を越えたものを作ろうとするライブラリもあります。最終的には新しい言語や文法を作ろうという流れになります。「元言語に新しい文法を追加する」というのの2つの流れがあるわけです。一般論として言うと、ライブラリの提供する機能があまり汎用的ではない場合には、ドメイン特化言語(DSL)として元言語から分離して「汎用言語+DSL混在開発」する。汎用的ならば元言語を言語拡張するのが自然な流れかと思います。以下のようなものを紹介したいと思います。元言語のモデリングパラダイムを越えようとしているようなものもあったり。新しいパラダイムを作ろうとしていたり、1つの言語として扱うに足りるものもあります。最終的には新しい言語になることが多いです。(逆に、受け入れられず人知れず消えていくことも多々。言語に対するプリプロセスで実現されていていました。ライブラリとして提供されてるハードウェア設計言語。ソフトウェア的に動作検証もできるし、ハードウェア記述を生成することも可能。パラダイム(オブジェクト指向)よりも抽象度の高いモデル(システムレベル設計)を扱おうとしているので、1つの言語として扱われることが多いです。最初に書いたとおり、こういう元言語よりも抽象度の高い新しいパラダイムを目指す物は、いずれは独立した言語になっていくものなんですが。業界標準の地位に納まりそうな雰囲気。並列プログラミング機能を追加するためのライブラリ。(対応していないコンパイラには無視される)擬似命令を使って記述。並列化されないだけで動作結果は一致するように書ける。プロセッサ向け開発環境はこれを使ってるらしい。並列化プログラミングパラダイムなんて、まさに過渡的な状況の真っ只中。いう書式がプログラマーにとって書きやすいのかとか、パフォーマンスがよくなるかとか、まだ研究段階というかきっちりと固まっていない感じ。使ったりといった、「対応していないコンパイラへの配慮」みたいなものが必要なんだと思います。メタプログラミング言語によっては、言語内に別のミニ言語を構築できるような機能を持つものがあります。DSL)を構築してから、そのミニ言語を使ってプログラミングを行うというのが日常茶飯事です。動的スクリプト言語が好んでこういうアプローチを取りたがるんですが、こういう機能をメタプログラミングといいます。使った例をあげてみます。PowerShell」。本来、クラスを定義するための構文がありません。使って書いたものを読み込んで使う。以下のような構文でクラスもどきを作ることができます。コンストラクタになります。このクラスを利用する側は以下のような感じ。本にこういう話があるらしい。ここで例に挙げたコードは、その話を聞いて自作してみたもの。その本を読んだことはないんでこれであってるかわからないけど。LibClass.ps1。TestLibClass.ps1。正体はいずれも関数だったりします。見ての通り、結構無理やりです。単なる自己満足と捕らえるか、あるいは、むしろ無茶苦茶なコード生みかねない欠点と考えるか、結構人それぞれなんですが。一般にはあまりはやってはいません。ミニ言語作成の難易度が高いという問題もありますが、メタプログラミングの問題はそれだけではないと思います。普通のプログラミングがやりやすい言語と、メタプログラミングしやすい言語は違うというものです。逆に、普通のプログラミングがしにくい言語です。持っている構文が貧弱で、むしろ、「メタプログラミングしてからじゃないとろくに使えない言語」という側面もあります。言語内に複数の設計方針が混在してしまうという問題もあります。クラスが定義できる状態になっています。クラスを使えるので、それほど変には思わないとは思いますが。やろうと思えばもっと奇抜な構文を作ったりもできます。やれることが多いというのは利点であると同時に欠点でもあります。なんでも自由にさせるよりも、ある程度のガイドラインで束縛した方が生産性が高かったりします。上述のような奇抜な構文作りは、さらに悪いことに、みんな好き勝手に構文を作れるわけです。下手すると、まったく同じことやるのに2つの別の構文ができるなんてことも起こりうる。ミニ言語を作った本人はいいですが、それ以外の人にとってはたまったものじゃない。新しい言語っていうのは、作るのはもちろん、覚えて使うってのも結構な重労働です。構文からして奇抜なものなんてなかなか覚えられません。統合開発環境)などのツールのサポートを受ける前提で作られています。ツールが優秀になっていて、サポートを受けながらなら学習も利用もずいぶん楽になっています。作成のハードルが高くなっています。作ったのに、ツールのサポートがないから結局汎用言語の方が楽」という事態も起こっています。元言語に新構文として取り入れられたりします。内部言語的アプローチの1つの終着点は、このような言語構文の拡張だと思います。いう構文が本当に有用かどうかの判断には長い時間がかかります。言語仕様が無駄に膨れ上がって逆に使いにくくなる可能性もあります。「モデル化」で言ったように、よいモデルというのは、必要十分で過不足のないものです。何でもかんでもやろうとすると複雑すぎて逆に何もできなくなります。言語拡張は慎重に行うべきです。汎用的に使えそうなものは言語拡張というのが大まかな方針になりそう。風のデータベース問い合わせ言語を統合するものです。)これ、もろに「メタプログラミングの問題」でいったような「言語設計方針の混在」なんですよね。オブジェクト指向プログラミング(OOP)パラダイムとリレーショナルデータベース(RDB)パラダイムの混在。いいことずくめでもなく、混乱の原因になるかもしれないものです。目指すところは「混在」ではなくて「統合」です。実際の問い合わせはライブラリまかせ、という仕様です。今後言語仕様に劇的な変化がありそうにもないです。言語の仕様がかなりしっかり固まっている」という3点があって初めて追加された構文だと思います。埋め込むことができます。型のインスタンスが生成されるみたい。ある程度の要望はあります。これも、単なる構文糖で、実際はライブラリ呼び出しに変換されます。標準的な地位を持っています。標準であり続けるか、あるいは仕様の拡張があったりしないか、というのを考えると、この言語拡張は結構リスキーなんですよね。ないのはそういう理由からです。言語コード中に埋め込める機能があります。(標準機能ではないですが、ほとんどのコンパイラがこの機能を持っています。)これも一種の言語内言語ですよね。異なる抽象度の混在開発が目的ですが。(一般に、抽象度が低い方が細かいチューニングができて、ピーク性能はよくなります。労力に見合わないし、人的ミスによってかえってパフォーマンスが落ちたりしますが、ボトルネックになっている部分だけ抽象度を下げることで性能向上を目指します。)まあ、「限界までチューニングを求められる分野」というのを特殊な開発領域だと考えるなら、この抽象度混在開発もドメイン特化型開発の一種とみなせます。ほんとにソース内に別言語を埋め込める仕組みがあるみたい。実際には外部のコンパイラ・インタプリタ呼び出すみたいです。(見た目は内部言語的、実質は外部言語的。作った実行モジュールのロード・関数のコールみたいな部分を自動化してくれる機能。いう方式は、やりすぎるとソースファイルの中身が何なのか分からないカオスな状態になります。異なるパラダイムが1つのソースに混在するのはやはりあまりよいものではありません。異なる言語間の橋渡しをする方が主流です。expander(直訳するなら構文拡張器?)ってのがあるみたい。構文拡張では、まず、パース(構文解析)用の関数を自分で書かないといけません。