As Leonid mentions in [one of his answers](http://mathematica.stackexchange.com/a/109917/34008) one of the methods of managing complexity is using [Domain Specific Languages (DSL's)](https://en.wikipedia.org/wiki/Domain-specific_language). In this answer I will provide links to documents, packages, blog posts, and discussions of creating and utilizing DSLs in *Mathematica*.

For a 2.5 minutes introduction see [this video](http://www.wolfram.com/broadcast/video.php?c=400&v=1470) between 25:00 and 27:30.

**When to apply DSL's**

Here are some situations for applying DSL.

1. When designing conversational engines.

2. When there are too many usage scenarios and tuning options for the developed algorithms.

* For example, we have a bunch of search, recommendation, and interaction algorithms for a dating site. A different department designs interactive user interfaces for these algorithms. We make a natural language DSL that invokes the different algorithms according to specified outcomes.


3. When designing an API for a collection of algorithms.

* Just designing a DSL can bring clarity of what signatures should be in the API.

* `NIntegrate`'s `Method` option was designed and implemented using a DSL. See [this video](http://www.wolfram.com/broadcast/video.php?c=400&v=1470) between 25:00 and 27:30.

**Designing DSL**

1. Decide what kind of sentences the DSL is going to have.

* Are natural language sentences going to be used? 

* Are the language words known beforehand or not?
	
2. Prepare, create, or accumulate a list of representative sentences.

* In some cases using [Morphological Analysis](https://en.wikipedia.org/wiki/Morphological_analysis_(problem-solving)) can greatly help for coming up with use cases and the corresponding sentences.   	

3. Create a context free grammar that describes the sentences from the previous step. (Or a large subset of them.)

* At this stage I use exclusively [Extended Backus-Naur Form (EBNF)](https://en.wikipedia.org/wiki/Extended_Backus–Naur_Form).

4. Program parser(s) for the grammar.

* I use most of the time [functional parsers](https://en.wikipedia.org/wiki/Parser_combinator).

* The package [FunctionalParsers.m](https://github.com/antononcube/MathematicaForPrediction/blob/master/FunctionalParsers.m) provides a *Mathematica* implementation of this kind of parsing.

* The package can automatically generate parsers from a grammar given in EBNF. (See the coding example below.)

5. Program an interpreter for the parsed sentences. 

* At this stage the parsed sentences are hooked to the algorithms of the problem domain.

* The package FunctionalParsers.m allows this to be done fairly easy.

6. Test the parsing and interpretation.

See the example below illustrating steps 3-6.

**Introduction to using DSLs in Mathematica**

1. This blog post of mine ["Natural language processing with functional parsers"](https://mathematicaforprediction.wordpress.com/category/functional-parsers/).

2. This detailed slide-show presentation ["Functional parsers for an integration requests language grammar"](https://github.com/antononcube/MathematicaForPrediction/blob/master/Documentation/Functional%20parsers%20for%20an%20integration%20requests%20language%20grammar.pdf) shows how to use the package [FunctionalParsers.m](https://github.com/antononcube/MathematicaForPrediction/blob/master/FunctionalParsers.m) over a small grammar.


**Advanced example**

The blog post ["Simple time series conversational engine"](https://mathematicaforprediction.wordpress.com/2014/11/29/simple-time-series-conversational-engine/) discusses the creation (design and programming) of a simple conversational engine for time series analysis (data loading, finding outliers and trends.)

Here is movie demonstrating that conversation engine: [http://youtu.be/wlZ5ANglVI4](http://youtu.be/wlZ5ANglVI4).

**Other discussions**

1. Small part from 17:30 to 21:00 of the WTC 2012 ["Spatial Access Methods and Route Finding"](http://www.wolfram.com/broadcast/video.php?sx=Spatial%20Access%20Methods%20and%20Route%20Finding&v=35) presentation shows a DSL for points of interest queries.

2. The [answer](http://mathematica.stackexchange.com/questions/49052/css-selectors-for-symbolic-xml/49053#49053) of the MSE question ["CSS Selectors for Symbolic XML"](http://mathematica.stackexchange.com/questions/49052/css-selectors-for-symbolic-xml) uses [FunctionalParsers.m](https://github.com/antononcube/MathematicaForPrediction/blob/master/FunctionalParsers.m).

**Coding example**

This example is for the steps 3-6 of the second section.

Load the package:

     Import["https://raw.githubusercontent.com/antononcube/MathematicaForPrediction/master/FunctionalParsers.m"]

Give a EBNF description of a DSL for food craviings:

    ebnfCode = "
      <lovefood> = <subject> , <loveverb> , <object-spec> <@ \
    LoveFood[Flatten[#]]& ;
      <loveverb> = ( 'love' | 'crave' | 'demand' ) <@ LoveType ;
      <object-spec> = ( <object-list> | <object> | <objects> | <objects-mult> ) \
    <@ LoveObjects[Flatten[{#}]]& ;
      <subject> = 'i' | 'we' | 'you' <@ Who ; 
      <object> = 'sushi' | [ 'a' ] , 'chocolate' | 'milk' | [ 'an' ] , 'ice' , \
    'cream' | 'a' , 'tangerine' ;
      <objects> = 'sushi' | 'chocolates' | 'milks' | 'ice' , 'creams' | \
    'ice-creams' | 'tangerines' ; 
      <objects-mult> = 'Range[2,100]' , <objects> <@ Mult ;
      <object-list> = ( <object> | <objects> | <objects-mult> ) , { 'and' \
    \[RightTriangle] ( <object> | <objects> | <objects-mult> ) } ; ";

Generate parses from EBNF string:

    GenerateParsersFromEBNF[ToTokens@ebnfCode];

Test the parsers with a list of sentences:

    sentences = {"I love milk", "We demand 2 ice creams", 
      "I crave 2 ice creams and 5 chocolates", 
      "You crave chocolate and milk"}; ParsingTestTable[pLOVEFOOD, 
     ToLowerCase@sentences, "Layout" -> "Horizontal"]

[![enter image description here][1]][1]

Next we implement interpreters. I am using `WolframAlpha` to get the calories. I gave up figuring out using `EntityValue["Food",___]`. (Since using is `WolframAlpha` it can be overridden inside `Block`.)


    LoveObjectsCalories[parsed_] :=
      Block[{res, wares(*, WolframAlpha={}&*)},
        res = (StringJoin @@ 
              Flatten[Riffle[parsed, " and "] /. 
                Mult[{x_, y_}] :> (StringJoin @@ 
                   Riffle[Flatten[{ToString[x], y}], " "])]);
         wares = WolframAlpha[res <> " calories", "DataRules"];
          {{"Result", 1}, "ComputableData"} /. wares 
            /. {{"Result", 1}, "ComputableData"} -> 
             Quantity[RandomInteger[{20, 1200}], "LargeCalories"]
       ];

    LoveFoodCalories[parsed_] :=
      Block[{who, type},
       who = Cases[parsed, Who[id_] :> id, \[Infinity]][[1]];
       type = Cases[parsed, LoveType[id_] :> id, \[Infinity]][[1]];
       Which[
        who == "you",
        Row[{"No, I do not. I am a machine."}],
        type == "love",
        Row[{"you gain ", Sqrt[1*10.] parsed[[-1]], " per day"}],
        True,
        Row[{"you will gain ", parsed[[-1]]}]
       ]
      ];

Here the parsing tests are done by changing the definitions of the wrapping symbols `LoveFood` and `LoveObjects`.

    Block[{LoveFood = LoveFoodCalories, LoveObjects = LoveObjectsCalories},
     ParsingTestTable[pLOVEFOOD, ToLowerCase@sentences, "Layout" -> "Vertical"]
    ]

[![enter image description here][2]][2]


  [1]: https://i.sstatic.net/hreAy.png
  [2]: https://i.sstatic.net/xTmas.png