I do not want to create a primer or answer the question as to what a DSL is (domain specific language) but I recognize that the line between a successful programming language and a ubiquitous uber programming language is somewhere between the range of problems that a language can solve. For example languages like C, C++, and assembler are excellent for low level programming but one can get tangled at high level. Languages like Go, C#, erlang and Java (CLR, Mono, JVM, Beam/EVM) are better at medium level challenges and most dynamic languages like perl, Ruby, JavasScript and Python are better at high level problems.
Going back to Dave Thomas’s (pragprog) AU Ruby Conf keynote. Paraphrasing: The power of any DSL is that it’s ideally suited for the complexity of the challenge it solves making the programmer productive.
A side note: I have purposefully left out languages like CoffeeScript, Elixir and Clojure because they are more akin to translations than they are standalone; and they simply do not solve any more problems than they inherit from their environments etc…
Up until this point in the argument I have been examining these languages from the level at which the programming interacts or develops application. From this perspective languages are broken into 3 components. (1) syntax; (2) APIs; (3) execution.
syntax; The differences in most languages is most dramatic in the syntax. It’s the place where most novice language designers think the definition of a DSL is. Almost all syntax looks the same. That’s probably because todays language tools like YACC and LEX, BNF etc help the language designer get to market quickly. So with the exception of concepts like Object-Oriented, lambda, and closures (and some other concepts) I think it’s safe to say that ALL modern programming languages are more similar than they are different.
APIs; unless the language provides direct access to the system hardware like registers and memory; everything, if exposed, is going to be provided in the APIs. The difference between the high and low level language APIs is the amount of protection the API provides for the user and the overall efficiency and implementation. For example ‘C’ lets the operating system detect the memory errors while Java and C# perform that task (whether they defer to the OS and intercept or preempt is not important)
My requirements for the ideal DSL: