Archive for the ‘English’ Category.

Implicit conversions in Scala are cool

Andy Warhol – Dollar sign

Sometimes I hear sentences like Domain Specific Languages (DSL) can be generated effectively only using dynamic languages, or This super-cool feature could not be possible in a static typed language. More and more, some people would transmit the idea that dynamic languages are agile and cool, while static ones are rigid and old. I strongly disagree! I think that in static languages lots of unit tests are generated and maintained automatically by the compiler, while in dynamic ones the programmer should create and maintain these tests. So static languages have lots more unit tests: isn't this agile programming? And what about cool features? Well, what do you think about a language in which you can write something like this?

 
(5.0 USD) + (2.0 USD) == (7.0 USD)

Cool DSL, isn't it? Sure, and I will show you that this is possible (and very easy) using a language with a strong and static type system: Scala.

As we are going to write yet another money example, we could begin with the definition of currencies.

 
abstract class Currency {
  def name: String;
  override def toString = name
}    
 
object Euro extends Currency {
  def name ="EUR"
}    
 
object Dollar extends Currency {
  def name = "USD"
}

Not very exciting. We simply define an abstract Currency class and two singleton objects that extend this class. Note that these objects are instances of anonymous subclasses of Currency. This does matter, as we'll see in a moment.

Now let's define money.

 
case class Money[C <: Currency](amount: Double, currency: C) {
  def + (otherMoney: Money[C]) = {
    new Money(amount + otherMoney.amount, currency)
  }
  override def toString = amount + " " + currency
}

Our class is parametric in the type C, and we tell to the compiler that it must be a subclass of Currency. This way we have the nice consequence that the + operator can add only money of the same currency, and this test is done by the compiler before our code is running.

It's time to get to the cool feature: implicit conversion. So, in the same file Money.scala in which we defined the Money class, we create a Money object, which has the responsibility to convert doubles, let me say, "annotated" with a currency, into Money.

 
object Money {
  implicit def doubleConverter(d: Double) = new {
    def EUR = {
      new Money(d, Euro)
    }    
 
    def USD = {
      new Money(d, Dollar)
    }
  }
}

Uhm, it sounds a bit strange. How we can use it? Let's see an example.

 
import Money._    
 
object MoneyMainProgram extends Application {    
 
  val tenDollars = (4.0 USD) + (6.0 USD)     
 
  println(tenDollars)
}

Now some explanations are required.

In the first line we import the Money object. We can see it as a kind of static import, that, among other things, adds to the scope of our code all the implicit conversions defined in that object.

When we write 4.0 USD, we try to invoke the USD method on the 4.0 object, which is a double. Obviously there isn't such a method in the Double class, but the compiler, before giving up and throwing an error, tries to see if there is some way to convert the 4.0 in an object that does understand the USD method. Luckily we have imported the doubleConverter which takes a Double and transforms it in an instance of an anonymous class with a USD method: bingo! So the compiler transforms our code in something like this:

 
  doubleConverter(4.0).USD()

But what is the result of this expression? Well, it's an instance of the Money class expressed in Dollar. This class has the + method that we can use to add another Money in the same currency. Cool!

Let's take a look to our work. We needed to add some features to the Double class. In some dynamic languages we could monkey patch this class. In Scala we did it using a dynamic conversion from Double to a class with the methods we need, so we reached the same purpose in a static and safer way.

And so, an old fashioned static language could have such cool features? It seems....

Pleasures of boilerplate code

In a very interesting interview, Martin Odersky said that Scala could be a little more difficult than Java for newcomers because in it you have not to write boilerplate code, but you have to think at your problem just from the first line of code. In some way, boilerplate code could be a kind of "warming up" for beginners. Writing some code, even if it's only syntactic noise, could give confidence to the programmer, generating a feeling of accomplishment.

But, is there a way to warm up without writing silly code? The best way of doing this is with unit testing. In TDD by example , Kent Beck describes "Starting tests": Start by testing a variant of an operation that doesn't do anything. Using these tests, not only you can start exploring your design, but you can also break the "white sheet syndrome".

Things I do not like in Scala

As you can guess, I'm a fan of the Scala programming language. Nevertheless, unlike some Ruby evangelists, I can say that there is something in my favourite programming language that I don't like. Here are some examples.

Semicolon inference

The first one is about how Scala considers the end of statements.
Let's take a look at this code.

 
package bad   
 
object BadScala {   
 
  def subtractVersion1(a: Int, b: Int) = {
    a -
    b
  }   
 
  def subtractVersion2(a: Int, b: Int) = {
    a
    - b
  }   
 
  def main(args : Array[String]) : Unit = {
    println(subtractVersion1(10, 2))
    println(subtractVersion2(10, 2))
  }
}

The output of this program is

8
-2

Unlike Java, Scala does not require semicolons to close a statement. In Programming in Scala we can read

A line ending is treated as a semicolon unless one of the following conditions is true:
1. The line in question ends in a word that would not be legal as the end of a statement, such as a period or an infix operator.
2. The next line begins with a word that cannot start a statement.
3. The line ends while inside parentheses (...) or brackets [...], because these cannot contain multiple statements anyway.

So in method subtractVersion1 there is only one statements that spans two lines, giving a - b as return value. In subtractVersion2 the compiler infers a semicolon at the end of the first line, so the result value is -b.

The missing equal sign

Now let's see how forgetting an equal sign could be dangerous.

 
package hello   
 
object BadScala2 {   
 
  def myFavouriteLanguage1() = {
    "Scala"
  }   
 
  def myFavouriteLanguage2() {
    "Ruby"
  }   
 
  def main(args : Array[String]) : Unit = {
    println(myFavouriteLanguage1)
    println(myFavouriteLanguage2)
  }
}

This program gives as output:

Scala
()


(It seems that there is no way to make me say that Ruby is my favourite language ;-) )

The only difference between the above two methods myFavouriteLanguage1 and myFavouriteLanguage2 is a missing equal sign. In Scala if a method declaration does not have an equal sign before its body, the compiler infers that the result type will be Unit (something like void in Java). So, as also the return keyword is optional (and, in fact, it's never used in idiomatic Scala), the method will not give any result, or, we should say, a result which type is Unit, and it's rendered as ().

Is Scala a bad programming language?

So is Scala a bad programming language? In my humble opinion, Scala is a really powerful programming language, the best one I have learned so far. Anyway, in it there is a trade-off between power and safeness. We should know its weakness in order to use it effectively and enjoy its power.