La distinzione è difficile da fare e dipende dalla lingua utilizzata. È anche soggettivo.
In clojure, è possibile definire API che sembrano DSL. Ad esempio, il singhiozzo ti consente di generare html:
(html [:span {:class "foo"} "bar"])
Questo può essere considerato come un DSL con una sintassi lisp. Il fatto che html
potrebbe essere una macro dà la stessa quantità di potenza di se stessi scrivendo una libreria di template HTML con espressioni S (vedi sxml )
In Python, la stessa API può apparire come:
html(["span", {"class" : "foo"}, "bar"])
html è una funzione. Il suo argomento verrà valutato per primo, quindi verrà eseguita la chiamata di funzione. Il fatto che la sintassi di Python sia più specifica e che la semantica di Python sia più rigorosa significa che questa espressione è più difficile da interpretare come una DSL indipendente dal linguaggio.
Una rappresentazione linguistica classica è un albero come una struttura di dati e una funzione di valutazione chiamata ricorsivamente sui suoi nodi. I linguaggi LISP rendono questa struttura ad albero molto evidente, quindi qualsiasi chiamata di funzione nidificata è indistinguibile da una funzione di linguaggio integrata. Ecco perché la comunità LISP parla di DSL per quasi tutto.
Credo che la programmazione consista nel fornire astrazioni utili. Trovo che guardare tutto ciò che costruisci (una lib o persino l'interfaccia utente della tua applicazione) come elementi linguistici che aiutano le persone a risolvere un problema complesso sia un modo efficace per progettare la maggior parte delle cose. In questa prospettiva, asserisco che tutte le librerie sono DSL, ma alcune di esse sono progettate male :-)