Wann wird eine API als eingebettetes DSL betrachtet?

10

Was ist der Unterschied zwischen einer API und einer eingebetteten domänenspezifischen Sprache (DSL)?

Ist es nur Syntax?

Betrachten Sie eine API wie OpenGL. Wie unterscheidet sich das von einem Grafik-DSL?

Mit anderen Worten, wenn eine API ausreichend komplex ist, kann sie als eingebettetes DSL betrachtet werden?

Phyllostachys
quelle
1
Der Sinn eines DSL ist es, die Dinge einfacher zu machen. Sollten Sie nicht fragen, ob eine ausreichend einfache API als DSL angesehen werden kann?
Doval
Ich nehme an, ich möchte wissen / verstehen, wie API und DSLs unterschieden werden. Ich habe dort Komplexe eingefügt, weil ich denke, dass wenn man ständig eine API aufruft, diese eher domänenspezifisch ist, oder zumindest habe ich das ursprünglich so gedacht.
Phyllostachys
1
Die Frage ist, was ist der Unterschied zwischen einer API und einem eingebetteten DSL ?
Proskor

Antworten:

8

Die Unterscheidung ist schwer zu treffen und hängt von der verwendeten Sprache ab. Es ist auch subjektiv.

In clojure können Sie APIs definieren, die wie DSL aussehen. Mit hiccup können Sie beispielsweise HTML generieren:

(html [:span {:class "foo"} "bar"])

Dies kann als DSL mit einer Lisp-Syntax betrachtet werden. Die Tatsache, dass es htmlsich um ein Makro handeln könnte, gibt ihm die gleiche Leistung, als ob Sie eine HTML-Vorlagenbibliothek mit S-Ausdrücken schreiben würden (siehe sxml ).

In Python sieht dieselbe API möglicherweise folgendermaßen aus:

html(["span", {"class" : "foo"}, "bar"])

HTML ist eine Funktion. Das Argument wird zuerst ausgewertet, und dann wird der Funktionsaufruf ausgeführt. Die Tatsache, dass die Python-Syntax spezifischer ist und die Python-Semantik strenger ist, bedeutet, dass dieser Ausdruck als DSL unabhängig von der Sprache schwerer zu interpretieren ist.

Eine klassische Sprachdarstellung ist eine baumartige Datenstruktur und eine Bewertungsfunktion, die auf ihren Knoten rekursiv aufgerufen wird. LISP-Sprachen machen diese Baumstruktur sehr deutlich, sodass jeder verschachtelte Funktionsaufruf nicht von einer integrierten Sprachfunktion zu unterscheiden ist. Deshalb spricht die LISP-Community für fast alles über DSLs.

Ich glaube, beim Programmieren geht es darum, nützliche Abstraktionen bereitzustellen. Ich finde, dass es eine effektive Möglichkeit ist, die meisten Dinge zu entwerfen, wenn Sie alles, was Sie erstellen (eine Bibliothek oder sogar die Benutzeroberfläche Ihrer Anwendung), als Sprachelemente betrachten, die Menschen bei der Lösung eines komplexen Problems helfen. Mit dieser Perspektive behaupte ich, dass alle Bibliotheken DSLs sind, aber einige von ihnen sind schlecht gestaltet :-)

Simon Bergot
quelle
4

APIs und DSLs sind sehr unterschiedliche Konzepte, und es gibt nur einige Bereiche, in denen sie sich möglicherweise überschneiden.

Alle DSLs sind Computersprachen . Sie können interpretiert, kompiliert, markiert, Abfragesprachen (z. B. SQL) oder (wie JSON oder einige Verwendungen von XML) Datensprachen sein, die in Nachrichten verwendet werden können, die über eine API übertragen werden. Sie müssen jedoch Sprachen sein . Der Begriff beschreibt die Natur , nicht den Zweck.

APIs sind Schnittstellen, über die eine Softwarekomponente von anderen Komponenten verwendet werden kann. Der Begriff beschreibt den Zweck , nicht die Natur. Eine API kann beispielsweise eine Reihe von Objektmethoden sein - das ist kein DSL. Eine Web-API verwendet möglicherweise ein DSL (oder, wenn es ruhig ist, können Sie argumentieren, dass es sich um ein DSL handelt), aber eine gemeinsam genutzte, domänenspezifische Sprache ist nicht Teil der Definition. Ein Softwaretreiber für ein Gerät kann in C geschrieben sein, die API wird als kompilierte Bibliothek verteilt, das Protokoll ist vollständig binär und jede Sprache, die die Bibliothek verwenden kann, kann verwendet werden, um einen Client zu erstellen. Nichts in dieser API kann als DSL bezeichnet werden (eine Liste symbolischer Namen für die API-Funktionen schneidet es nicht).

Ich bin ein wenig verwirrt darüber, warum man angesichts der Definitionen nur Ähnlichkeiten sehen kann.

itsbruce
quelle
Wie ein Kommentator betonte, muss ich nur eingebettete DSLs berücksichtigt haben. Stellen Sie sich etwas wie Forth vor, bei dem man ein Wörterbuch mit Wörtern erstellt. Ich habe gelesen, dass das Erstellen einer DSL-Datei fast vollständig ist, aber es scheint einer API sehr ähnlich zu sein.
Phyllostachys
2
Was meine Antwort nicht wirklich beeinflusst. Wenn es sich um eine Sprache mit eigener Syntax usw. handelt, handelt es sich um DSL. Eine komplexe Schnittstelle, der diese Sprachfunktionen fehlen, ist kein DSL. Sie sollten Ihre Frage wahrscheinlich aktualisieren, und ich werde erwägen, meine Antwort zu aktualisieren.
Itsbruce
2
Eine Subsprache ist immer noch eine Sprache. Es ist nicht erforderlich, eine "eigene" Syntax zu haben, sondern kann diese aus der Host-Sprache "ausleihen".
Proskor
Sind dann nicht alle Projekte ihre eigenen DSLs, wenn sie gerade fertig sind (dh allgemeine Programmiersprachen sind schließlich DSLs)? Eine Art Kontinuum von allgemein bis domänenspezifisch.
Phyllostachys
4

Im Allgemeinen nein. Ein DSL wird absichtlich nicht allgemein gehalten, um einige Operationen bequemer zu machen. Dinge wie HTML oder Logo waren ursprünglich domänenspezifische Sprachen.

Im Allgemeinen können Sie DSL auch mit der leistungsstärksten API nicht in eine andere Sprache einbetten. Was auch immer Sie gegen diese API programmieren, sieht immer noch wie eine Reihe von Ausdrücken in der Hostsprache aus und ist nicht so bequem wie die Verwendung einer Spezialsprache.

Ausnahmen sind Sprachen, die außergewöhnliche Möglichkeiten bieten, die Syntax über eine Bibliothek zu verzerren (Überladen von Operatoren wie C ++, Erfinden neuer Operatoren wie Scala oder sogar Deklarieren einer völlig anderen Lesesyntax wie Perl mit Quellfiltern). Wenn Sie eine solche Sprache verwenden und die Flexibilität, die sie bieten, voll ausnutzen, kann das Ergebnis eher wie eine neue Spezialsprache aussehen (aber die Semantik unterscheidet sich oft geringfügig von dem, was Sie erwarten würden, wenn die Sprache wirklich erfunden würde von Grund auf, um Ihren Zwecken zu dienen).

Kilian Foth
quelle
Vielleicht könnte man also eine Sache machen, die einen String (DSL) analysiert, der als einfacher Wrapper für eine große API fungiert. Ich nehme an, die Trennung des DSL von dem, was das DSL analysiert, ist die Differenzierung.
Phyllostachys
3
Ja, das wird als "Interpreter" -Designmuster bezeichnet, und es wird als bewährte Methode angesehen: Sie schreiben den Interpreter-Code einmal und können von da an Ihren domänenspezifischen Inhalt viel einfacher ausdrücken.
Kilian Foth
"Neue Operatoren wie Groovy erfinden" Vielleicht meinten Sie Scala; In Groovy ist der Operator festgelegt, kann aber wie in C ++ überladen werden.
Vorg van Geir
@ VorgvanGeir Sorry, behoben.
Kilian Foth
2

Hier aus DslBoundary von Martin Fowler

Aus dem Artikel geht hervor, dass im Grunde genommen eingebettete DSLs und APIs nicht so unterschiedlich sind. Hier gibt es jedoch einen kleinen Unterschied.

  1. API legt Wert auf die Bereitstellung einer neuen Einrichtung.
  2. DSL bietet Ihnen nicht nur eine neue Funktion, sondern auch eine neue Syntax und die neue Art der Codierung.

Aber wenn über externes DSL gesprochen wird , wird es eine andere Geschichte sein. Das externe DSL ist wie eine kleine Programmiersprache, aber es ist sicher keine Allzwecksprache, was bedeutet, dass es nicht alle Probleme lösen kann, sondern ein spezifisches Problem.

fronthem
quelle
1

Ich denke, jede API ist eine eingebettete DSL, aber das Gegenteil ist nicht der Fall: Nicht jede eingebettete DSL ist eine API. Nur wenn die Sprache als Mittel zur Integration von Komponenten verwendet wird, kann sie als API bezeichnet werden.

Warum kann eine API als eingebettetes DSL betrachtet werden? Erstens bildet es eine Sprache: Es enthält primitive Elemente (Typen und Operationen), die (mithilfe der Hostsprache) kombiniert werden können, um Abstraktionen zu bilden und komplexe Probleme zu lösen. Mit der OpenGL-API können beispielsweise 3D-Szenen in Echtzeit gerendert werden. Die Sammlungs-API kann verwendet werden, um Algorithmen zu erstellen, die mit Objektgruppen usw. arbeiten. Zweitens ist sie offensichtlich domänenspezifisch. Beispielsweise verarbeitet die Domäne der Sammlungs-API Objektgruppen, und die Domäne der OpenGL-API ist 3D-Rendering. Daher ist eine API eine domänenspezifische Sprache.

Aber nicht jedes DSL ist eine API. Beispielsweise dürfen einige DSLs nicht von einer bestimmten Komponente implementiert werden. Alle Systeme definieren einige Abstraktionen, und die Abstraktionen, die sich mit einer bestimmten Domäne befassen, können als DSL betrachtet werden. Dies bedeutet jedoch nicht, dass die Implementierungen dieser Abstraktionen "austauschbar" sein sollten, dh sie müssen keine API bilden . Sie könnten, aber das ist nicht immer notwendig. In Fällen, in denen die Implementierung "komponiert" ist (Entschuldigung für das Fehlen eines besseren Begriffs), wird DSL tatsächlich zu einer API.

Proskor
quelle
Ist das nur deine Meinung oder kannst du es irgendwie unterstützen?
Mücke
@gnat Ich habe meine Antwort erweitert, um meinen Standpunkt weiter zu erläutern.
Proskor