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 html
moż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 :-)