APIと埋め込みドメイン固有言語(DSL)の違いは何ですか?
単なる構文ですか?
OpenGLのようなAPIを検討してください。それはグラフィックDSLとどう違うのですか?
つまり、APIが十分に複雑な場合、それは組み込みDSLと見なすことができますか?
区別は難しく、使用する言語によって異なります。それも主観的です。
Clojureでは、DSLのように見えるAPIを定義できます。たとえば、hiccupを使用すると、htmlを生成できます。
(html [:span {:class "foo"} "bar"])
これは、LISP構文のDSLと見なすことができます。 html
がマクロである可能性があるという事実は、s-expressionsを使用してhtmlテンプレートlibを作成している場合と同じように機能します( sxml を参照)。
Pythonでは、同じAPIは次のようになります。
html(["span", {"class" : "foo"}, "bar"])
htmlは関数です。その引数が最初に評価され、次に関数呼び出しが行われます。 python構文がより具体的であり、pythonセマンティクスがより厳密であるという事実は、この式が言語に依存しないDSLとして解釈することがより困難であることを意味します。
古典的な言語表現は、データ構造のようなツリーと、そのノードで再帰的に呼び出されるeval関数です。 LISP言語では、このツリー構造が非常にはっきりしているため、ネストされた関数呼び出しは組み込みの言語機能と区別できません。これが、LISPコミュニティがほとんどすべてのDSLについて語っている理由です。
プログラミングは、有用な抽象化を提供することだと思います。ビルドしたすべてのもの(ライブラリーまたはアプリケーションのUI)を、人々が複雑な問題を解決するのを助ける言語要素として見ることは、ほとんどのものを設計するための効果的な方法であることがわかりました。この観点から、私はすべてのライブラリーがDSLであると断言しますが、それらのいくつかは設計が不十分です:-)
一般的には違います。 DSLは、意図的にsome操作をより便利にするために、一般的ではありません。 HTMLやロゴのようなものは、もともとドメイン固有の言語でした。
一般的に、最も強力なAPIを使用しても、DSLを別の言語に埋め込むことはできません。そのAPIに対してプログラムするものはすべて、依然としてホスト言語の一連の式のように見え、特殊目的言語を使用する場合ほど便利ではありません。
例外は、ライブラリを介して構文をワープする例外的な機会を提供する言語です(C++のような演算子のオーバーロード、Scalaのような新しい演算子の発明、またはソースフィルター付きのPerlのような完全に異なる読み取り構文の事前宣言)。そのような言語を使用し、それらが提供する柔軟性を最大限に活用すると、結果は新しい特別な目的の言語のように見えます(ただし、セマンティクスは、言語がそうであった場合に期待するものと微妙に異なることがよくあります- 本当に目的を達成するために根本から発明された)。
APIとDSLはまったく異なる概念であり、重複していると言える領域がいくつかあります。
すべてのDSLはコンピューター言語です。それらは、APIを介して渡されるメッセージで使用される可能性がある、解釈、コンパイル、マークアップ、クエリ言語(SQLなど)または(JSONまたはXMLの一部の使用など)データ言語である可能性がありますが、言語。この用語は、目的ではなく、自然を説明しています。
APIは、1つのソフトウェアコンポーネントを他のコンポーネントで使用できるようにするインターフェイスです。この用語は、性質ではなく、目的を説明しています。たとえば、APIはオブジェクトメソッドのセットにすることができます。つまり、DSLではnotではありません。 Web APIはDSLを使用する場合があります(または、落ち着いている場合、DSLはDSLです)と主張できますが、共有されたドメイン固有の言語は定義の一部ではありません。デバイスのソフトウェアドライバーはCで記述されている場合があり、APIはコンパイル済みライブラリとして配布され、プロトコルは完全にバイナリであり、ライブラリを使用できる任意の言語を使用してクライアントを作成できます。そのAPIの何もDSLと呼ぶことはできません(API関数のシンボル名のリストはそれをカットしません)。
定義を考えると、類似点しか表示されない理由について少し混乱しています。
ここでは、 DslBoundary からMartin Fowler
記事から、私の理解は基本的に埋め込まれたDSLとAPIはそれほど違いはないということです。ただし、ここには少し違いがあります。
しかし、外部DSLについて話すと、別の話になります。外部DSLは小さなプログラミング言語に似ていますが、確かに、それはすべての問題を解決することはできず、代わりに特定の問題を解決することを意味する汎用言語ではありません。
私はすべてのAPIが組み込みDSLであると思いますが、逆は当てはまりません。すべての組み込みDSLがAPIであるとは限りません。コンポーネントを統合する手段として言語が使用されている場合にのみ、APIと呼ぶことができます。
APIが組み込みDSLと見なされるのはなぜですか?まず第一に、それは言語を形成します:それは抽象を形成し、複雑な問題を解決するために(ホスト言語によって)組み合わせることができるプリミティブ要素(タイプと操作)を持っています。たとえば、OpenGL APIを使用して、リアルタイムで3Dシーンをレンダリングできます。コレクションAPIは、オブジェクトのセットなどを操作するアルゴリズムを作成するために使用できます。次に、それは明らかにドメイン固有です。たとえば、Collections APIのドメインはオブジェクトのセットを処理し、OpenGL APIのドメインは3Dレンダリングです。したがって、APIはドメイン固有の言語です。
ただし、すべてのDSLがAPIであるとは限りません。たとえば、一部のDSLは指定されたコンポーネントによって実装されません。すべてのシステムはいくつかの抽象化を定義しており、特定のドメインを扱う抽象化はDSLと見なすことができますが、これらの抽象化の実装が「スワップ可能」である必要があることを意味しません。つまり、APIを形成する必要はありません。それらは可能ですが、常に必要なわけではありません。ただし、実装が「コンポーネント化」されている場合(より適切な用語がないため申し訳ありません)、DSLは実際にAPIになります。