CSC/ECE 517 Fall 2010/ch2 S23 SS

From Expertiza_Wiki
Jump to navigation Jump to search

Domain Specific Object Oriented Languages


Introduction

Domain Specific Language (DSL) is any programming language which is designed to solve some specific problems and tasks in a specific domain. These languages are very focused and restricted to particular problem domain. This is in contrast to general programming languages (GPL) like java or C++ which can be used for software development in many application domains. Examples for DSL include:

  • SQL for relational database
  • Verilog for statistics
  • Latex for typesetting

Object Oriented DSL's (OODSL) are DSL's based on object oriented programming paradigm. They employ the idea of classes and objects with concepts like encapsulation, polymorphism, abstraction etc. OODSL's like any other DSL's are much more expressive in their domain and much less comprehensive than general purpose object oriented programming languages like Java, C# etc. They are high-level languages, in the sense that they abstract from low-level implementation details. Some OODSL examples are Rails based on ruby programming language and JSP tags, Hibernate and Spring based on Java.

Pros and Cons of OODSL

Like any other DSL, employing OODSL in any application domain comes with its own set of advantages and disadvantages. Some of them are discussed below.

Pros of using OODSL for application development are:

  • OODSL's are developed for a particular domain and hence can handle the problems related to that domain. They help express solution in the idiom and abstraction of problem domain and can be easily understood by experts in that domain.
  • OODSL's are much simpler to use than general purpose language in their domain.
  • They are concise, self documented and easy to understand and hence aid in easy development, maintainability and productivity

On the other side, cons of using OODSL are:

  • Developing an OODSL require effort and cost.
  • OODSL has limited scope within their domain.
  • Using a newly developed OODSL requires users to understand its syntax.
  • Using OODSL together with GPL constructs can be a difficult task.

Types of OODSL

OODSL can be of two types, internal and external :

Internal OODSL are the ones which use a host language and give them the feel of a particular language. Developing internal OODSL's is comparatively simple as they use grammar, parsers and tools of underlying language. But they are constrained by the underlying language. The challenge is to design these languages so as to have syntax within the confines of host language, yet these languages are simple, concise and fluent. An example of internal OODSL would be Rake (make equivalent) based on host, Ruby.Internal OODSL's are also referred as embedded languages or fluent interfaces.

External OODSL, on the other hand is designed to be independent of any other language. Syntax, grammar, parsing of these languages is pretty much based on its author choice and gives both pain and pleasure of developing all from scratch. Example of external DSL would be Ant based on java.

History of OODSLs

History of DSL dates back than modeling approaches used now to develop them. Initial DSL's were developed many decades before. Worth mentioning is FORTRAN developed in late 1950s, an abbreviation of 'formula translation'. FORTRAN borrowed notation from mathematics so that programmers could write mathematical formulas directly. OODSL's started coming up after object oriented paradigm became prominent in 1970's and 1980's. OODSL's appeared mostly in late 1980's and 1990's. Now, OODSL's are used in web applications (e.g. Rails), computer games and environments (e.g. MOO programming) and as programming languages for music (e.g. Formes).

OODSL Examples

Some examples of OODSL prevalent today are:

  • Kiddo - Kiddo is an internal OODSL based on ruby and used for building silverlight and WPF applications. Kiddo is based on ideals of "kid friendly" coding and has 5 core methods to get started with drawing.
  • ColdFusion Markup Language - Commonly known as CFML, it is a scripting language used by Adobe's ColdFusion and other scripting engines. The CFML includes a set of tags that can be used in ColdFusion pages to interact with data sources and display output.
  • MOO Programming Language - Moo programming language is used to support Mud Object Oriented or MOO server which is online virtual reality system to which multiple players can connect at the same time. Its domain is computer gaming environment.
  • LPC - It is an object-oriented programming language derived from C and developed originally to facilitate MUD building. It was designed for game development.
  • Formes - It is an object-oriented DSL used for music composition and synthesis. It is written in VLISP.
  • R - R is a programming language for statistical computing and graphics. R has stronger object-oriented programming facilities than most statistical computing languages available.
  • Kermeta - Kermeta is a meta-modeling language used to describe structure and the behavior of models. Kermeta can be used as the core language for a model oriented platform.

Creating an OODSL

OODSL can be created using many techniques and tools available in the market.

Properties of any OODSL

Any OODSL should be fluent and in context.

  • Fluency: A fluent OODSL should have interfaces which are properly designed for human use and has high readability and natural flows within the language. An example explaining fluency is given below:

Looping through any collection in java was done traditionally as:

for(int i = 0; i < products.size(); i++)
{
 String name = (String) products.get(i);
 //...
 //.....
 
}

However it can be done more fluently starting Java 5 as:

for(String product : products)
{
// ...
// ...
}

This flow comes naturally to any user and is easier to interpret.

  • Context: OODSL should have a proper context on which they are built upon, after all, they are domain specific. Shared context makes OODSL easier to understand and work with and highly expressive. For example:

In java declaring and adding into the cart is done as:

java.util.ArrayList<String> cart = new java.util.ArrayList<String>();
cart.add("Milk");
cart.add("Juice");
cart.add("Apple");
System.out.print("My cart has %d items.", cart.size())

Same thing can be done in groovy as:

cart = []
cart.with {
 add "Milk"
 add "Juice"
 add "Apple"
 println "My cart has $size items."
}

Languages like Groovy and javascript are easier than java to build context such that convention is followed.

Examples taken from: http://www.javaworld.com/javaworld/jw-07-2008/jw-07-dsls-in-java-2.html?page=3

Techniques/Tools used

There are many OO languages like Smalltalk, ruby, groovy which easily lend themselves for creating internal OODSL. Ruby provides expressive, flexible syntax and has a dynamic nature which makes implementing a new OODSL easy without using any additional parser or compiler. Also, groovy easily supports creating fluent and in context OODSL's. On the other hand, C++ or Java syntax is not easy to attain the level of fluency required for a DSL, and so creating internal OODSLs using these languages is challenging. However, these languages offer good parsing libraries or capabilities and their support for creating external DSL’s is pretty strong.

Tools like visual studio and ANTLR aid in creating OODSL. Visual studio contains Domain-Specific Language Designer Wizard which provides many solution templates which can be used to create an OODSL. ANTLR, ANother Tool for Language Recognition, is another language tool that provides a framework for constructing recognizers, interpreters, compilers, and translators from grammatical descriptions. It supports many runtime libraries of ruby, C#, java etc which helps to create internal OODSL.

There are four basic approaches used for creating OODSL. These are:

  • Instantiation: This approach is used mostly in Ruby projects, and not even recognized as a DSL. Using this approach, DSL is defined by defining methods of an object. Interaction is like any other OODSL, done by instantiating the object and calling the methods. The HTML creation DSL of Ruby’s CGI class uses this approach.
  • Class macros: DSL is defined as methods on some ancestor class, and those methods are tweaked to modify the behavior of super-class and for subclasses of the particular class in question. These kinds of macros often create new methods. “has_many” in ActiveRecord is a good example of this type of approach.
  • Top-level methods: There exists a configuration file, which is just like a Ruby script augmented with some DSL syntax. Any application using this type of DSL will load this configuration and uses DSL top level methods defined. When those methods are called in the configuration file, they modify some central (typically global) data, which then application uses to determine how it should execute. Rake is an example of this kind of DSL.
  • Sandboxing: This approach is a special case of the more general instantiation technique. Using this technique, DSL is defined as methods of some object which is really just a “sandbox”. Interaction with the object’s methods modifies state of the sandbox which is queried by the application. This technique is similar to the top-level methods technique, with an exception that the DSL is restricted to the sandbox and there are no global methods involved. Needle uses this approach.

Steps to create an OODSL

Some of the steps which can be used to create an OODSL are:

  • Identifying the goals to be accomplished.
  • Reasoning why creating a new OODSL would be better than existing well crafted OODSL or an API.
  • Defining ideal syntax before even coding.
  • Referring to other examples of OODSL's, learning from their code and looking at the similarities.
  • Refining syntax to get the best Return on Investment. If creating an internal OODSL, it is best to take advantage of host language’s compiler and adapting syntax slightly without creating a new full fledged parser or compiler.

Example

Below is an example of how an OODSL for creating SQL statements and querying database systems can be created. It is compared with how the same task is done in general purpose language.

Dynamic construction of an SQL statement in Java :

String sql = "select id, name " +
            "from customers c, order o " +
            "where " +
            "c.since >= sysdate - 30 and " +
            "sum(o.total) > " + significantTotal + " and " +
            "c.id = o.customer_id and " +
            "nvl(c.status, 'DROPPED') != 'DROPPED'"; 

The same can be written using OODSL as follows :

Table c = CUSTOMER.alias();
Table o = ORDER.alias();
Clause recent = c.SINCE.laterThan(daysEarlier(30));
Clause hasSignificantOrders = o.TOTAL.sum().isAbove(significantTotal);
Clause ordersMatch = c.ID.matches(o.CUSTOMER_ID);
Clause activeCustomer = c.STATUS.isNotNullOr("DROPPED");
String sql = CUSTOMERS.where(recent.and(hasSignificantOrders)
                      .and(ordersMatch)
                      .and(activeCustomer)
                      .select(c.ID, c.NAME)
                      .sql(); 

The SQL statement written in Java requires developer to be familiar with Oracle-SQL. This may not be the case for every application development in every domain. An OODSL like above can help in these cases. Creating basic classes representing different constructs of SQL query makes creating query easy. E.g. Class “Table” represents a basic API available through DSL and is used for representing tables which are to be queried. Creating different clauses using class “Clause” help filter data from the database.

The DSL code is less procedural, more declarative and object-oriented. It also has several advantages, major one being creating SQL statements without having familiarity of how to write SQL statements in database packages like Oracle, MySQL etc. The commonly used phrase, “nvl(c.status, 'DROPPED') != 'DROPPED'" in Oracle SQL cannot be easily understood by a non-SQL programmer. By replacing this phrase with the more easily understandable and language-like "isNotNullOr(“DROPPED”)," readability has been enhanced, and the system is protected from a later need to change the implementation to take advantage of facilities offered by another database vendor.

Note: The above example was explained in an easier manner. Further reading can be done from original source, http://www.infoq.com/articles/internal-dsls-java

Summary

This article gives some basic overview of OODSL features. OODSLs are mainly used in the domain of software engineering. The challenge using software engineering is to create flexible, reliable, scalable and maintainable systems. To achieve this, the software engineer must apply a wide variety of tools and techniques. One of these is to take advantage of the knowledge from underlying application domain, by means of a domain-specific language (DSL), which provides a notation that can be used to compose applications from a set of concepts tailored towards a specific application domain. Creating OODSL is a good option because OODSL provides benefits from both the worlds, DSL and OO concepts. An OODSL can be easily extended later, if required, which may not be the case with any other DSL. Hence it can be said that, OODSLs provide a certain level of abstraction of a domain, which can result in a greater control over or understanding of that domain. At the same time, they provide some good features of object oriented programming.

References

[1] Eelco Visser. WebDSL: A Case Study in Domain-Specific Language Engineering. Lecture Notes in Computer Science, 2008, Volume 5235/2008, 291-373.

[2] Martin Fowler. MF Bliki: DomainSpecificLanguage. Retrieved September 15, 2010, from, http://www.martinfowler.com/bliki/DomainSpecificLanguage.html

[3] Domain-specific Language. Wikipedia, the Free Encyclopedia. Retrieved September 15, 2010 from http://en.wikipedia.org/wiki/Domain-specific_language.

[4] Jeff Barczewski. Creating DSL’s in Ruby. Retrieved September 16, 2010 from http://inspiredhorizons.com/presentations/CreatingDSLsInRuby-060926.pdf

[5] Venkat Subramaniam, Creating DSL’s in java. Retrieved September 16, 2010 from http://www.java2s.com/Article/Java/Development/DSL.htm

[6] Jamis Buck. Writing Domain Specific Languages. Retrieved September 16, 2010 from http://weblog.jamisbuck.org/2006/4/20/writing-domain-specific-languages

[7] Alex Ruiz, Jeff Bay. An Approach to Internal Domain-Specific Languages in Java Retreved September 16, 2010 from http://www.infoq.com/articles/internal-dsls-java

[8] ColdFusion Markup Language. Wikipedia, the Free Encyclopedia. Retrieved September 15, 2010 from http://en.wikipedia.org/wiki/ColdFusion_Markup_Language

[9] MOO. Wikipedia, the Free Encyclopedia. Retrieved September 15, 2010 from http://en.wikipedia.org/wiki/MOO

[10] Freedom Dumlao. Introducing Kiddo: A Ruby DSL for building simple WPF and Silverlight applications. Retrieved September 15, 2010 from http://weblogs.asp.net/freedomdumlao/archive/2010/05/27/introducing-kiddo-a-ruby-dsl-for-building-simple-wpf-and-silverlight-applications.aspx

[11] LPC (programming language). Wikipedia, the Free Encyclopedia. Retrieved September 15, 2010 from http://en.wikipedia.org/wiki/LPC_(programming_language)

[12] Kermeta Language Overview. Retrieved September 15, 2010 from https://www.kermeta.org/docs/KerMeta-MetaModel.pdf