Creating and programming domain specific languages

Introduction

In this blog post I will provide links to documents, packages, blog posts, and discussions for creating and utilizing Domain Specific Languages (DSLs). I have discussed a few DSLs in previous blog posts (linked below). This blog post provides a more general, higher level view on the application and creation of DSLs. The concrete examples are with Mathematica, but the steps are general and can be done with any programming languages and tools.

When to apply DSLs

Here are some situations for applying DSLs.

  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, User Experience Department (UED) designs interactive user interfaces for these algorithms. We make a natural language DSL that invokes the different algorithms according to specified outcomes. With the DSL the different designs produced by UED are much easily prototyped, implemented, or fleshed out. The DSL also gives to UED easier to understand view on the functionalities provided by the algorithms.
  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 between 25:00 and 27:30.

Designing DSLs

  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 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).
    • In some cases the grammar terminals are not know at the design stage and have to retrieved in some way. (From a database or though natural language processing.)
    • Some conversational engine systems allow or require to the grammar specification to be done in XML. I would still do BNF and then move to XML
      •  It is not that hard to write a parser-and-interpreter that translates BNF into XML. See the end of this blog post for that kind of translation of BNF into OMPL.
  4. Program parser(s) for the grammar.
    • I use most of the time functional parsers.
    • The package 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.)
    • I have programmed versions of this package in R and Lua.
  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 code example below illustrating steps 3-6.

Introduction to using DSLs in Mathematica

  1. This blog post “Natural language processing with functional parsers” gives an introduction to the DSL application in Mathematica.
  2. This detailed slide-show presentation “Functional parsers for an integration requests language grammar” shows how to use the package FunctionalParsers.m over a small grammar.
  3. The answer of the MSE question “How to parse a clojure expression?” gives a good introduction with a simple grammar and shows both direct parser programming and automatic generation from EBNF.

Advanced example

The blog post “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 a movie demonstrating that conversational engine: http://youtu.be/wlZ5ANglVI4.

Other discussions

  1. A small part, from 17:30 to 21:00, of the WTC 2012 “Spatial Access Methods and Route Finding” presentation shows a DSL for points of interest queries.
  2. The answer of the MSE question “CSS Selectors for Symbolic XML” uses FunctionalParsers.m .
  3. This Quantile Regression presentation is aided by the  “Simple time series conversational engine” mentioned above.

Coding example

This coding example demonstrates steps 3-6 discussed above.

EBNF-and-parsers-for-LoveFood

Interpreters-and-parsing-for-LoveFood

Object-Oriented Design Patterns in Mathematica

Introduction

In this blog post I would like to proclaim a recent completion of the first version of a document describing how to implement the most important (in my view) Object-Oriented Programming Designed Patterns by GoF.

Here is the link to the document in MathematicaForPrediction at GitHub:

“Implementation of Object-Oriented Programming Design Patterns in Mathematica”  , [1].

That document presents a particular style of programming in Mathematica (Wolfram Language) that allows the application of the Object-Oriented Programming (OOP) paradigm. The approach does not require the use of preliminary implementations, packages, or extra code. Using the OOP paradigm is achieved by following a specific programming style and conventions with native, fundamental programming constructs in Mathematica’s programming language.

A side product of working on this document is a Mathematica package for creating UML diagrams proclaimed in previous post, “UML diagram creation and generation”.

Below are several topics I consider most important not covered or briefly considered in that document.

Related presentation

Here is a video recording of my presentation “Object Oriented Design Patterns” at the Wolfram Technology Conference 2015. The presentation recording is also uploaded at YouTube.

Here is link to the presentation notebook : “Object-Oriented Design Patterns with Wolfram Language”.

Why use design patterns in Mathematica

For large development projects it is a good idea to use the well established, understood, and documented Design Patterns. Design Patterns help overcome limitations of programming languages, give higher level abstractions for program design, and provide design transformation guidance. Because of extensive documentation and examples, Design Patterns help knowledge transfer and communication between developers.

Because of these observations it is much better to emulate OOP in Mathematica through Design Patterns than through emulation of OOP objects. (The latter is done in all other approaches and projects I have seen.)

As it was said above the proposed method is minimalistic: native language features of Mathematica are used.

The larger context of Design Patterns

This diagram shows the large context of patterns:

VennDiagramForPatternsInGeneral-smallThe Mathematica implementations discussed in [1]  are for “Design Patterns by GoF”. One of the design patterns “Interpreter” is extended with the package FunctionalParsers.m that uses the so called “monadic programming”. (Hence the overlap of “Design Patterns by GoF” with “Functional programming patterns”.)

In order to provide a feel for the larger context in the diagram I have referenced the book “Go Rin no Sho”(“The book of five scrolls”) by Miyamoto Musashi. We can say that the book contains patterns applicable in antagonistic conflicts. It presents the patterns in abstract forms applicable to person-to-person fights, battles between armies, or other antagonistic settings. Another interesting idea in this book is that if you practice the explained strategy with a samurai sword you will become capable applying that strategy when leading an army.

Personal experiences with design patterns

I was introduced to OOP Design Patterns in the conferences ECOOP’99. At the time I was working on my Ph.D. in the field of large scale air pollution simulations.

Air pollution simulations over continents, like Europe, are grand challenge problems that encompass several scientific sub-cultures: computational fluid dynamics, computational chemistry, computational geometry, and parallel programming. I did not want to just a produce an OOP framework for addressing this problem — I wanted to produce the best OOP framework for the set of adopted methods to solve these kind of problems.

One way to design such a framework is to use Design Patterns and did so using C++. Because I wanted to bring sound arguments during my Ph.D. defense that I derived on of the best possible designs, I had to use some formal method for judging the designs made with Design Patterns. I introduced the relational algebra of the Database theory into the OOP Design Patterns, and I was able to come up with some sort of proof why the framework written is designed well. More practically this was proven by developing, running, and obtaining results with different numerical methods for the air-pollution problems.

In my Ph.D. thesis I showed how to prove that Design Patterns provide robust code construction through the theory Relational Databases, [2].

Justifying Design Patterns with the theory of Relational Databases

One of the key concepts and goals in OOP is reuse. In OOP when developing software we do not want changes in one functional part to bring domino effect changes in other parts. Design Patterns help with that. Relational Databases were developed with similar goals in mind — we want the data changes to be confined to only one relevant place. We can view OOP code as a database, the signatures of the functions being the identifiers and the function bodies being the data. If we bring that code-database into a third normal form we are going to achieve the stability in respect to changes desired in OOP. We can interpret the individual Design Patterns as bringing the code into such third normal forms for the satisfaction of different types of anticipated code changes.

References

[1] Anton Antonov, “Implementation of Object-Oriented Programming Design Patterns in Mathematica”, (2016), MathematicaForPrediction project at GitHub.

[2] Anton Antonov, Object-oriented framework for large scale air pollution models, 2001. Ph.D. thesis, Informatics and Mathematical Modelling, Technical University of Denmark, DTU.

 

 

UML diagrams creation and generation

This post is to show how to create and generate Unified Modeling Language (UML) diagrams in Mathematica. It is related to programming in Mathematica using Object-Oriented Design Patterns.

Although this post is not about prediction per se it is going to be referenced and used in future posts about predictive algorithms and challenges.

Package functions

This command imports the package UMLDiagramGeneration.m :

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

The package provides the functions UMLClassNode and UMLClassGraph.

The function UMLClassNode has the signature

UMLClassNode[classSymbol, opts]

UMLClassNode creates a Grid object with a class name and its methods for the specified class symbol. The option “Abstact” can be used to specify abstract class names and methods. The option “EntityColumn” can be used to turn on and off the explanations column.

The function UMLClassGraph that has the signature:

UMLClassGraph[symbols, abstractMethodsPerSymbol, symbolAssociations, symbolAggregations, opts]

UMLClassGraph creates an UML graph diagram for the specified symbols (representing classes) and their relationships. It takes as options the options of UMLClassNode and Graph.

UML diagrams creation

Let us visualize a simple relationship between buildings, people, books, and a client program.

UMLClassGraph[{Library \[DirectedEdge] Building,
Museum \[DirectedEdge] Building,
Member \[DirectedEdge] Person}, {}, {Library <-> Member,
Museum \[DirectedEdge] Member, Client \[DirectedEdge] Building,
Client \[DirectedEdge] Person}, {Library \[DirectedEdge] Book},
"Abstract" -> {Building, Person},
"EntityColumn" -> False, VertexLabelStyle -> "Text",
ImageSize -> Large, GraphLayout -> "LayeredDigraphEmbedding"]

UML-diagram-for-Inheritance-Composition-Association

In the diagram above the classes Person and Building are abstract (that is why are in italic). Member inherits Person, Library and Museum inherit Building. Library can contain (many) Book objects and it is associated with Member. Client associates with Building and Person.

UML diagram generation

The main package function UMLClassGraph is capable of generating UML diagrams over Design Patterns code written in the style exemplified and described in my WTC 2015 talk Object-Oriented Design Patterns.

Let us look into a simple UML generation example for the design pattern Template Method.

Here is the Mathematica code for that design pattern:

 Clear[AbstractClass, ConcreteOne, ConcreteTwo];
 
 CLASSHEAD = AbstractClass;
 AbstractClass[d_]["Data"[]] := d;
 AbstractClass[d_]["PrimitiveOperation1"[]] := d[[1]];
 AbstractClass[d_]["PrimitiveOperation2"[]] := d[[2]];
 AbstractClass[d_]["TemplateMethod"[]] :=
 CLASSHEAD[d]["PrimitiveOperation1"[]] + CLASSHEAD[d]["PrimitiveOperation2"[]]
 
 ConcreteOne[d_][s_] := Block[{CLASSHEAD = ConcreteOne}, AbstractClass[d][s]]
 ConcreteOne[d_]["PrimitiveOperation1"[]] := d[[1]];
 ConcreteOne[d_]["PrimitiveOperation2"[]] := d[[1]]*d[[2]];
 
 ConcreteTwo[d_][s_] := Block[{CLASSHEAD = ConcreteTwo}, AbstractClass[d][s]]
 ConcreteTwo[d_]["PrimitiveOperation1"[]] := d[[1]];
 ConcreteTwo[d_]["PrimitiveOperation2"[]] := d[[3]]^d[[2]];

This command generates an UML diagram over the code above:

UMLClassGraph[{AbstractClass, ConcreteOne,
ConcreteTwo}, {AbstractClass -> {"PrimitiveOperation1",
"PrimitiveOperation2"}}, "Abstract" -> {AbstractClass},
VertexLabelStyle -> "Subsubsection"]

UML-diagram-generated-over-TemplateMethod-code

Here is a diagram generated over a Mathematica implementation of Decorator:

UML-diagram-for-Decorator

And here is a diagram for a concrete implementation of Interpreter for Boolean expressions:

UML-diagram-for-Interpreter-of-BooleanExpr

(Interpreter is my favorite Design Pattern and I have made several Mathematica implementations that facilitate and extend its application. See these blog posts of mine: “Functional parsers” category in MathematicaForPrediction at WordPress).