Kiedy interfejs API jest uważany za osadzony DSL?

10

Jaka jest różnica między interfejsem API a osadzonym językiem specyficznym dla domeny (DSL)?

Czy to tylko składnia?

Rozważ API takie jak OpenGL. Czym to się różni od graficznego DSL?

Innymi słowy, jeśli interfejs API jest wystarczająco złożony, czy można go uznać za osadzony DSL?

Phyllostachys
źródło
1
Celem DSL jest uproszczenie. Czy nie powinieneś pytać, czy wystarczająco prosty interfejs API można uznać za DSL?
Doval
Przypuszczam, że chcę wiedzieć / rozumieć, w jaki sposób są różnicowane API i DSL. Umieszczam tam skomplikowane, ponieważ uważam, że gdy ktoś ciągle wywołuje interfejs API, jest to raczej specyficzne dla domeny, a przynajmniej tak początkowo o tym myślałem.
Phyllostachys
1
Pytanie brzmi, jaka jest różnica między interfejsem API a wbudowanym DSL ?
proskor

Odpowiedzi:

8

Rozróżnienie jest trudne do wykonania i zależy od używanego języka. Jest to również subiektywne.

W clojure możesz zdefiniować interfejsy API, które wyglądają jak DSL. Na przykład czkawka pozwala wygenerować HTML:

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

Można to uznać za DSL ze składnią Lisp. Fakt, że htmlmoże to być makro, daje mu tyle samo mocy, co w przypadku pisania biblioteki HTML szablonów za pomocą wyrażeń s (patrz sxml )

W Pythonie ten sam interfejs API może wyglądać następująco:

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

HTML jest funkcją. Jego argument zostanie najpierw oceniony, a następnie nastąpi wywołanie funkcji. Fakt, że składnia języka Python jest bardziej szczegółowa, a semantyka języka Python jest bardziej rygorystyczna, oznacza, że ​​trudniej jest interpretować to wyrażenie jako DSL niezależne od języka.

Klasyczna reprezentacja języka to drzewiasta struktura danych i funkcja ewaluacyjna wywoływana rekurencyjnie w jej węzłach. Języki LISP sprawiają, że ta struktura drzewa jest bardzo widoczna, więc każde zagnieżdżone wywołanie funkcji jest nie do odróżnienia od wbudowanej funkcji językowej. Właśnie dlatego społeczność LISP mówi o DSL do prawie wszystkiego.

Wierzę, że programowanie polega na dostarczaniu użytecznych abstrakcji. Uważam, że patrząc na wszystko, co budujesz (lib, a nawet interfejs użytkownika aplikacji) jako elementy języka pomagające ludziom rozwiązać złożony problem, jest skutecznym sposobem na zaprojektowanie większości rzeczy. W tej perspektywie twierdzę, że wszystkie biblioteki to DSL, ale niektóre z nich są źle zaprojektowane :-)

Simon Bergot
źródło
4

Interfejsy API i DSL to zupełnie inne pojęcia i istnieją tylko niektóre obszary, w których można powiedzieć, że się pokrywają.

Wszystkie DSL są językami komputerowymi . Mogą być one interpretowane, kompilowane, znaczniki, języki zapytań (np. SQL) lub (jak JSON lub niektóre zastosowania XML) języki danych, które mogą być używane w komunikatach przekazywanych przez interfejs API, ale muszą to być języki . Termin opisuje naturę , a nie cel.

Interfejsy API to interfejsy umożliwiające korzystanie z jednego komponentu oprogramowania przez inne komponenty. Termin opisuje cel , a nie naturę. API może być na przykład zbiorem metod obiektowych - to nie jest DSL. Interfejs API sieci Web może korzystać z DSL (lub, jeśli jest spokojny, możesz argumentować, że jest to DSL), ale wspólny, specyficzny dla domeny język nie jest częścią definicji. Sterownik oprogramowania dla urządzenia może być napisany w C, interfejs API dystrybuowany jako skompilowana biblioteka, protokół całkowicie binarny, a dowolny klient, który może korzystać z biblioteki, może zostać użyty do stworzenia klienta. Nic w tym interfejsie API nie można nazwać DSL (lista symboli dla funkcji API go nie wycina).

Jestem trochę zdezorientowany, dlaczego widzisz tylko podobieństwa, biorąc pod uwagę definicje.

itsbruce
źródło
Jak zauważył komentator, musiałem brać pod uwagę tylko osadzone DSL. Zastanów się nad czymś takim, jak Forth, gdzie buduje się słownik słów. Przeczytałem o tym, gdy buduje się DSL, gdy zbliża się do posiadania kompletnej aplikacji, ale wygląda to jak API.
Phyllostachys
2
Co tak naprawdę nie wpływa na moją odpowiedź. Jeśli jest to język z własną składnią itp., To jest to DSL. Złożony interfejs pozbawiony tych funkcji językowych nie jest DSL. Prawdopodobnie powinieneś zaktualizować swoje pytanie, a ja rozważę aktualizację mojej odpowiedzi.
itsbruce
2
Podjęzyk jest nadal językiem. Nie trzeba mieć własnej „składni”, można „pożyczyć” ją z języka hosta.
proskor
Czy zatem nie wszystkie projekty mają swoje własne DSL, gdy są już prawie gotowe (tj. Ogólne języki programowania to w końcu DSL)? Rodzaj kontinuum od ogólnego do specyficznego dla domeny.
Phyllostachys
4

Ogólnie nie. DSL jest celowo niestandardowy, aby niektóre operacje były wygodniejsze. Rzeczy takie jak HTML lub Logo były pierwotnie językami specyficznymi dla domeny.

Zasadniczo nie można osadzić DSL w innym języku, nawet przy użyciu najbardziej wydajnego interfejsu API; cokolwiek programujesz w stosunku do tego interfejsu API, nadal będzie wyglądało jak seria wyrażeń w języku hosta i nie będzie tak wygodne, jak używanie języka specjalnego.

Wyjątkiem są języki, które zapewniają wyjątkowe możliwości wypaczenia składni za pomocą biblioteki (przeciążanie operatora, takie jak C ++, wymyślanie nowych operatorów, takich jak Scala, a nawet uprzedzanie zupełnie innej składni odczytu, takiej jak Perl, z filtrami źródłowymi). Kiedy używasz takiego języka i w pełni korzystasz z jego elastyczności, wynik może wyglądać raczej na nowy język specjalnego przeznaczenia (ale semantyka często będzie nieznacznie różnić się od tego, czego byś się spodziewał, gdyby język został naprawdę wynaleziony od podstaw, aby służyć twoim celom).

Kilian Foth
źródło
Być może można by zrobić coś, co analizuje ciąg (DSL), który działa jak zwykłe opakowanie dla dużego interfejsu API. Przypuszczam, że oddzielenie DSL od tego, co analizuje DSL, to różnicowanie.
Phyllostachys
3
Tak, to się nazywa wzorzec projektowy „tłumacza” i jest to uważane za dobrą praktykę: piszesz kod tłumacza jeden raz, a następnie możesz łatwiej wyrażać treści specyficzne dla domeny.
Kilian Foth
„wymyślanie nowych operatorów, takich jak Groovy” Być może miałeś na myśli Scalę; w Groovy zestaw operatora jest stały, ale może być przeciążony jak w C ++.
Vorg van Geir
@VorgvanGeir Przepraszamy, naprawiono.
Kilian Foth,
2

Tutaj, z DslBoundary autorstwa Martina Fowlera

Z tego artykułu rozumiem, że w zasadzie osadzone DSL i interfejsy API nie różnią się tak bardzo. Ale tutaj jest trochę różnicy.

  1. API kładzie nacisk na zapewnienie nowego obiektu.
  2. DSL zapewnia nie tylko nową funkcjonalność, ale także nową składnię i nowy sposób kodowania.

Ale jeśli mówimy o zewnętrznym DSL , będzie to inna historia. Zewnętrzny DSL jest jak mały język programowania, ale na pewno nie jest to język ogólnego przeznaczenia, co oznacza, że ​​nie może rozwiązać wszystkich problemów, ale konkretny problem.

fronthem
źródło
1

Myślę, że każdy interfejs API jest osadzonym DSL, ale odwrotność nie jest prawdą: nie każdy osadzony DSL jest interfejsem API. Tylko wtedy, gdy język jest używany jako środek do integracji komponentów, można go nazwać API.

Dlaczego interfejs API można uznać za osadzony DSL? Przede wszystkim tworzy język: ma prymitywne elementy (typy i operacje), które można łączyć (za pomocą języka hosta) w celu tworzenia abstrakcji i rozwiązywania złożonych problemów. Na przykład OpenGL API może być używany do renderowania scen 3D w czasie rzeczywistym. Interfejsu API kolekcji można używać do tworzenia algorytmów działających na zestawach obiektów itp. Po drugie, jest on oczywiście specyficzny dla domeny; na przykład domena interfejsu API kolekcji obsługuje zestawy obiektów, a domeną interfejsu API OpenGL jest rendering 3D. Dlatego API jest językiem specyficznym dla domeny.

Ale nie każda DSL jest interfejsem API. Na przykład niektóre DSL nie mają być implementowane przez wyznaczony komponent. Wszystkie systemy definiują niektóre abstrakty, a abstrakty dotyczące określonej domeny można uznać za DSL, ale nie oznacza to, że implementacje tych abstrakcji powinny być „wymienialne”, innymi słowy, nie muszą tworzyć interfejsu API . Mogliby, ale nie zawsze jest to konieczne. Jednak w przypadkach, gdy implementacja jest „składowa” (przepraszam za brak lepszego terminu), DSL rzeczywiście staje się interfejsem API.

proskor
źródło
czy to tylko twoja opinia, czy możesz to jakoś poprzeć?
komara
@gnat Rozszerzyłem swoją odpowiedź, aby dokładniej wyjaśnić moją opinię.
proskor