The task of developing a program to solve a specific problem involves two steps. The first step is to devise a solution procedure to solve the problem. This step requires a domain expert to use his/her domain knowledge, expertise, creativity and mental acumen to devise a solution to the problem. The second step is to code the solution in some executable notation (such as a computer programming language) to obtain a program that can then be run on a computer to solve the problem. In the second step the user is required to map the steps of the solution procedure to constructs of the programming language being used for coding. Both steps are cognitively challenging and require considerable amount of thinking and mental activity. The more we can reduce the amount of mental activity involved in both steps (e.g., via automation), the more reliable the process of software construction will be. Not much can be done about the first step as far as reducing the amount of mental activity is involved, however, a lot can be done for the second step. The amount of mental effort the programmer has to put in the second step depends on the ``semantic" gap between the level of abstraction at which the solution procedure has been conceived and the various constructs of the programming language being used. Domain experts usually think at a very high level of abstraction while designing the solution procedures. As a result, the more low-level the programming language, the wider the semantic gap, and the harder the user's task. In contrast, if we had a language that was right at the level of abstraction at which the user thinks, the task of constructing the program would be much easier. A domain specific language indeed makes this possible.
Note that for any kind of communication (including between programmers/users and the computer) the notation used for the communication determines how effectively and efficiently that communication can be understood/processed. A new, complex notation may take longer time to learn, but if the notation is carefully designed for the task/domain, then it allows far more complex things to be expressed and understood considerably more easily. It also encourages creativity, since people now have to simply focus on what to say, rather than on how to say it. This in turn affects productivity of the people (and machines) involved. A prime example of this is the position-based decimal notation for arithmetic, which allows for efficient algorithms for various arithmetic operations (addition, subtraction, multiplication, etc.) to be developed. Imagine developing a method similar to long division for the Roman numeral notation! The importance of notation cannot be overstated for programming. The proliferation of programming languages has come about due to our desire to find the ``right" language that will make it easy for programmers to express their algorithms (of course, the choice of algorithm some times depends on the notation being used, but here I use the term algorithm in a more general sense, namely, as a method for solving a problem). Since there can be no one perfect notation for all tasks, a plethora of programming languages have been developed, each one optimized for one particular type of use. One could take this proliferation to its logical conclusion and argue that one needs a dedicated (domain specific) programming language for each type of task and domain.
In the DSL based approach to software engineering, software engineers first design a domain specific language for the tasks at hand. The implementation of the software system then amounts to implementing a language processor (interpreter/compiler) for this domain specific language. End-users (who are usually domain experts) then write programs using this domain specific language. Dually, any software system can be viewed as a language processor. This is because any complex software system can be understood in terms of how a user will interact with it. A user interacts with a software system by providing input data and commands. Thus, to understand a software system, one has to understand the input language used to specify these data and commands. This input language, of course, can be regarded as a domain specific language. The software system can be thought of as imparting operational semantics to this input language. Thus, the task of developing a complex software system can be thought of as first designing its input language, and then implementing a language processor for this input language.
There are a number of advantages to taking this language centric approach to software development: (i) issues of usability of the software devolve to how well the input domain specific language has been designed; (ii) software development becomes syntax directed, i.e., the syntax of the DSL largely dictates how the software is developed. (iii) programs can be verified and provably correct machine code can be generated more easily. These are discussed in some more detail next.
First of all, the DSL should be (manually) designed. The design of the language will require the inputs of both computer scientists and domain experts. Once the DSL has been designed, we need its implementation infrastructure, i.e., a program development environment (an interpreter, a compiler, debuggers, profilers, editors, etc.), to facilitate the development of programs written in this DSL. Observe that the time taken to initially design the DSL is dependent on how rapidly the DSL can be implemented, since the ability to rapidly implement the language allows its designers to quickly experiment with various language constructs and with their various possible semantics.
Note also that like any other language, a domain specific language will evolve as it is used more and more to write programs. Users and language designers gain experience with use of a DSL as more and more programs are written. This inevitably results in language features being modified or added to the DSL. If the DSL changes, then obviously its implementation infrastructure must change as well. The success of the domain specific language methodology will depend on how rapidly this implementation infrastructure can be modified to reflect the changes in the language. Experience has shown that the time for a domain specific language to mature can be several years [16]. A significant part of this time is spent developing and modifying the implementation infrastructure as the DSL changes. Clearly, if the implementation infrastructure can be rapidly developed/modified, then the time for the DSL to mature will be reduced, making a DSL based approach to software engineering viable and practical.
With respect to the dual view of a software system as a language processor of its input language, the software specification phase amounts to designing the software's input language. The actual implementation of the software system then amounts to developing the implementation infrastructure of the input language.
With respect to the dual view of a software system as a processor of its input language, once the input language is designed, the software system (language processor) itself can be rapidly developed by specifying the (executable) syntax and semantics of the input language.
Note that it is not essential that one uses DCGs and declarative operational semantics for obtaining a language processor for the DSL. One could use `C' based implementations, however, these may make take longer to develop compared to the Horn logical approach. Additionally, the other benefits of using the declarative notation of Horn clauses, e.g., being able to verify programs or automatically obtain compiled code (so that the code generation process is provably correct), may be difficult to realize. Using a denotational (compositional) approach has the additional advantage that the development of the language processor (and, thus, of the software system) becomes syntax directed. This is because in the denotational approach, there is one semantic rule per syntax (grammar) rule. Additionally, compositionality implies that the semantic rules have to be specified in a way such that the meaning of a syntactic category is given in terms of meaning of its syntactic components. Thus, the Horn logical semantics based approach provides strong guidance on how the software is developed, making the software development process faster. Thus, the main challenge that remains in the software development process is the design of its input language (i.e., its syntax), the rest quickly follows.