Scala Nuggets: Look Ma! My First DSL

Posted on Wednesday, April 13, 2011

1


DSL (Domain Specific Language) is a programming language or specification language dedicated to a particular problem domain, problem representation or a particular solution technique. So with a few Scala Nuggets on our way we are ready to write a DSL? Not quite but in this post we would touch upon a critical feature in Scala which makes writing DSL’s easy.

Let us look at the following code snippet.

     println (1+2)
    println (1 .+(2))
    println (1.+(2))
    println (1 +(2))

and if I tell you that the output is the following

3
3
3.0
3

How do you interpret that? Well, the first one is easy and that is how we do it in Java also. What about println (1 .+(2)). How on earth can I do that?

In Scala, all operators are methods. So, in our example, + is actually a method which can be called on 1. Hence what we are essentially doing here is that we are calling 1.someMethod(2) and in our case someMethod happens to be +
Aha, and why is there a space between 1 and the period(.) This is because if we do not give the space, the compiler assumes that we are calling the method + on a Double. That is the reason that you see the output of println (1.+(2)) as 3.0
Ok and what the hell is println (1 +(2)). Well, actually it is the same thing as you can see from the output but Scala allows you to omit the period and the parentheses when the method takes only one argument. So we have omitted the period here and in the first line i.e. println (1+2), we have omitted both the period and the parentheses.

Also if a method takes no argument but is defined with empty argument list then we can call the method either by including the parentheses or omitting it. Hence the following

def methodWithNoArgs(){
    println("No Argument Method")
  }

can be accessed with either of the two

methodWithNoArgs
methodWithNoArgs()

However, if the method is defined with no parentheses, something like this

def methodWithNoArgsAndNoParenthesesEither{
    println("No Argument No Parantheses Method")
  }

then only this methodWithNoArgsAndNoParenthesesEither would work and methodWithNoArgsAndNoParenthesesEither() would not.

How does it help with DSL? Lets look at an example. There is a company called Inphina, which has a method call to see whether the Air Conditioning can we switched on or not.


object Inphina {

  def switchOnACat(n:Int):Boolean={
    if (n>35){
      return true
    }  else{
      return false
    }
  }

As you can see that the AC can be switched on when the temperature is > 35. Let us see how we can invoke it now. One way of calling is the routine way which is

val x = Inphina.switchOnACat(37);
    println(x)

Another way is to make it more reader friendly and more like English sentence

println(Inphina switchOnACat 37)

Since the switchOnACat method takes one argument hence we can omit the period and parentheses and get more readability.

What about the following

 (List(1, 2, 3, 4).filter(isEven)).foreach(println)
def isEven(n: Int) = (n % 2) == 0

Applying the above principles of method, period and parentheses, we get the same results with

List(1, 2, 3, 4) filter isEven foreach println

Cool isn’t it! We will get into advanced DSL on our way by consuming Scala Nuggets one by one!

Advertisements
Posted in: Java, Scala