Scala: Declaring variables and methods

The first thing that hit me in my first encounter in Scala is the different syntax for the declaration of variables.

In Scala it is defined in one of two ways:

val immutableValue: Int = 1
var mutableValue: Int = 2

The first line defines an immutable value (i.e. constant value) that doesn’t ever change and the second line defines a mutable value.

This differs from the Java equivalent:

final int immutableValue = 1;
int immutableValue = 2;

So far, the difference is only syntactic and individuals might prefer one syntax over the other as a matter of style. Nevertheless the Scala syntax does have a lot of practical advantages.

Firstly, Scala allows for the type of the variable to be omitted whenever the compiler is able to deduce it. That means I can write the following shorter alternative instead:

val immutableValue = 1
var mutableValue = 2

The shorter Scala version is also a lot easier to read.

Secondly, the syntax makes more complicated declarations more consistent. For instance why does Java sometimes put the generic types before the symbol being declared and sometimes after?

In the following Java code, the type argument T is declared after the interface name MyInterface whereas the type argument <U> appears before the method name foo.

public interface MyInterface<T> {
  public <U> U foo(U arg);
}

In Scala, the generic type delcarations always occur immediately after the symbol to which it appears:

trait MyTrait[T] {
  def foo[U](arg: U): U
}

The reason for the Java inconsistency is that it is difficult to write a parser for that will work for the syntax a Java programmer might prefer:

public interface MyInterface<T> {
  public U foo<U>(U arg);
}

This is because the foo method returns U, but the parser cannot know that U is a generic type – probably assuming it is a normal class name until it has found <U>, by then it has to undo all its assumptions.

It is telling that even C++ is adopting a syntax where the type comes after the symbol because designing a decent language with the C-like syntax for declarations is just too hard.

More consistent rules and fewer exceptions means a simpler language. It’s why I think Scala is how Java should have been designed.

Thirdly functions a first class value meaning I can treat them as normal objects and declare them easily:

lazy val fib: Int => Int = { n =>
  if (n < 2) {
    return 1
  } else {
    return fib(n - 1) + fib(n - 2)
  }
}

This defines the variable fib. Its type is a function that takes an argument of type Int and returns a value of type Int. The name of the argument is n. The variable declaration includes the lazy keyword because the function being defined is recursive. This delays the creation of the function object until the first use of the fib variable allowing the fib variable to occur first so that it is available for the function object to be created. There is no Java equivalent.

To call this function object, simply use the function call syntax:

println(fib(10))

Imagine how horrible it is to define something like this in Java. First I have to define the type of my function object because Java has no built-in concept of a function type:

public interface IntToInt {
  public int call(
      final int argument);
}

Then I have to define the function object via a anonymous class declaration:

final IntToInt[] fib = new IntToInt[1];
fib[0] = new IntToInt() {
  public int call(
      final int n) {
    if (n < 2) {
      return 1;
    } else {
      return fib[0].call(n - 1) + fib[0].call(n - 2);
    }
  }
};

And finally the function call:

System.out.println(fib[0].call(10));

The code is a disaster. It is twice as long and isn’t even generic. I might call this type IntToInt and the method call while someone else might call it FInt2Int and invoke respectively and even though these types represent the exact same concept, they aren’t compatible.

Furthermore, because the lack of a lazy keyword, in order to define a recursive function object, I need to declare a single element array. This is because anonymous classes can only access variables declared its scope if it is final. Yet when to the fib is defined to be a final variable of type IntToInt, the function object can’t reference it either because the attempt to create the function object occurs before the fib variable is defined.

To rub salt in the wound, the same thing can be written in one line of Scala:

lazy val fib: Int => Int = n => if (n < 2) 1 else fib(n - 1) + fib(n - 2)
About these ads
This entry was posted in scala, software development. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s