Трудно провести различие и зависит от используемого языка. Это тоже субъективно.
В clojure вы можете определить API, которые выглядят как DSL. Например, hiccup позволяет генерировать html:
(html [:span {:class "foo"} "bar"])
Это можно рассматривать как DSL с синтаксисом lisp. Тот факт, что это html
может быть макрос, дает ему такую же мощность, как если бы вы писали HTML- шаблонную библиотеку с s-выражениями (см. Sxml )
В Python тот же API может выглядеть так:
html(["span", {"class" : "foo"}, "bar"])
HTML это функция. Сначала будет оценен его аргумент, а затем произойдет вызов функции. Тот факт, что синтаксис python является более конкретным, а семантика python более строгим, означает, что это выражение труднее интерпретировать как DSL, независимый от языка.
Классическое представление языка - это древовидная структура данных и функция eval, вызываемая рекурсивно в его узлах. Языки LISP делают эту древовидную структуру очень очевидной, поэтому любой вызов вложенной функции неотличим от встроенной языковой функции. Вот почему сообщество LISP говорит о DSL практически для всего.
Я считаю, что программирование - это предоставление полезных абстракций. Я считаю, что рассмотрение всего, что вы создаете (библиотека или даже пользовательский интерфейс вашего приложения) как языковых элементов, помогающих людям решать сложные проблемы, является эффективным способом проектирования большинства вещей. С этой точки зрения я утверждаю, что все библиотеки являются DSL, но некоторые из них плохо спроектированы :-)