Thursday, January 3, 2013

A View of Scala from Java

A View of Scala from Java

Scala, according to its creator, Martin Odersky, was created as a fusion between functional and object oriented concepts in a statically typed language. This pragmatic approach behooves Java programmers to explore the ease in which they can start coding in Scala and as a natural progression start indulging into the functional aspects of the language. I have found Scala to be a good mix of Java transformed to the simpler syntax requirements of C# and powerful concepts inherited from earlier functional languages.

In this post, I plan to explore simple subset of differences between Java and Scala. The difference although simple can make your life lot easy and enjoyable! The objective is to motivate a Java programmer(and someone who probably has only written imperative style programs) to explore Scala without being exposed to the Scala's functional syntax and paradigms. The list is by no means comprehensive and I hope to add to this in the future. But, I see the productive of a Java programmer improve on adopting Scala.

Choose between explicit type declaration or implicit type inference

Scala takes a pragmatic approach and provides two options for type inference. You could use the strong explicit typing available in Java. Alternatively, you could let the Scala compiler do the type inference.

Java
Integer Sum(Integer x, Integer y) {
    return x + y;
}

Here is an simple example of implicit type inference in Scala. This kind of type inference would apply to lot other cases.

Scala

Sum(x: Integer, y: Integer): Int = x + y

or

Sum(x: Integer, y: Integer): = x + y

Here in the latter case, the return type is inferred based on the data type of x and y. So, in many cases declaring data types could be skipped, making code less verbose but still strongly typed.

Declare immutable objects

In Java you can use the final keyword to differentiate variables that are not mutable. Scala has two keywords val and var to differentiate between mutable and immutable types.

Though, Scala takes a pragmatic approach on supporting both functional and imperative form of programming, it leans towards the functional approach. It provides the keyword val to create immutable entities. Though, not recommended one can still use var in place of val which would reflect the regular behavior of Java.

Java

final int x = 10

Scala

val x:Int = 10 /* here the type in inferred if not specified*/

Arrays, List, Tuples

Arrays

Arrays in Scala have the same behavior as in Java. The elements of array are mutable.

Scala

val arrayExample = Array("This", "is", "an" "array", "of", "strings")
println(arrayExample(0))

Note, the use of () to access the element of the array. This syntax is closely related to how Scala treats every entity as an object and operations on them as method calls on the object.

Lists

The List data structure forms an important building block in many functional languages. A List object is immutable and any operation on the list will produce a new list which is the result of an operation applied to every element of the old list. Though, at first this may seem waste of memory when compared to regular imperative style programs, immutable objects provide lots of power to a language. There is no built-in equivalent to this in Java.

Lets take a quick look at some of the nice things once could do with Lists:

val list1 = List ( 1, 2, 3 )   //declare list of 3 elements of integers
val list2 = List ( 4, 5 , 6   //declare another list
val list3 = list1 ::: list 2  // returns a new list of 6 elements
list3.drop(2)  //return a new list without first 2 elements
list3.filter(s => s  > 4)  //return a list with elements 5 and 6

It is easy to notice that in Java, one might have implemented infinite number of for loops trying to do such lookups using iterators.

Another example, that would replace the explicit for loop would be:

list2.map(s => s+1)  // here we increment each element by one and produce
// another list. The parameters to the forall method
//is an lambda function which we will look at later.

For more examples of what can be done with Lists, you can refer here: List Operations

Tuples

Tuples is another data-type readily available in Scala. Logical sets of heterogeneous data can be tucked away into tuples.

Scala

val contact = ("dilbert", "programmer")
println(contact._1)  // the _1 is the syntax to access the elements of each tuple
println(contact._2)

Scala's Conveniences

A big advantage with these data types in Scala is the the comparison operators when applied to these types work on the each element of the type rather than the object references. I have enjoyed using this feature in other languages I have worked on, but dearly missed in both C# and Java.

val list1 = List ( 1, 2, 3 )   //declare list of 3 elements of integers
val list2 = List ( 4, 5 , 6 )  //declare another list
println(list1 == list2) // would return True

If Java implemented the List data structure its behavior would have been to return False for this comparison. In Scala, reference equality is provided with eq and ne operators.

Richer for loop syntax

Notice the data type definitions and the usage of for loop construct across the two languages

Java

ArrayList<Integer> x = new ArrayList<Integer>(3);
x.add(10);
x.add(11);
x.add(12);

for (Integer y:x)
{
    if ( y > 2 )
        System.out.println(y);
}

Scala

val x = new Array[Integer](3)  //type inferred for x
x(0) = 1
x(1) = 2
x(2) = 3

for (y <- x if y > 2)
    println(y)

The for expressions above give the same result and it might seem just a matter of style. But, for in Scala takes an expression as a parameter. That would mean that any kind of complex expression could be provided as a parameter before the for construct yields a list of items to work on.

A Singleton object without the synchronized keyword and race conditions

Scala offers a keyword called object used to create a singleton instance of the object implicitly. This also gets around the fact that Scala is purely-object oriented when compared to Java in the sense that it does not allow static methods or static members in a class definition.

Java

A typical Java implementation with all bells and whistles would look somewhat like this:

public class ClassicSingleton {
    private static ClassicSingleton instance = null;
    protected ClassicSingleton() {
  // Exists only to defeat instantiation.
  }
  public static ClassicSingleton getInstance() {
     if(instance == null) {
         instance = new ClassicSingleton();
         }
     return instance;
     }
 }

source:Design Patterns

Scala

object ClassicSingleton{
    private val x = new someobject()
    // other instance methods
    }

Here the object keyword informs the compiler that the ClassicSingleton class will be an singleton object.

Note, the reduction in complexity and LOC.

Get rid of tedious definitions of classes and boiler plate code

Let's construct a Person class in both the languages and then discuss the difference:

Java

class Person
{
 private String name;
    private int age;

    public Person(String n, int a)
    {
        if ( age < 18 ) {
            //throw IllegalArgumentException
            }
        name = n;
        age = a;
    }
}

Scala

class Person(name: String, age: Integer)
{
    require(age >= 18)


}

Here, Scala has a default constructor which creates object attributes based on the parameters. Note, these parameters are accessible later on with the field members. There are constructs like require that are used inside the class definition to validate parameters before the objects are instantiated.

Identifiers names are very flexible and can accept special characters.

Therefore, a method can be named + and this name could work as an overloaded operator in Scala. This is technically a function and there is no concept of operator overloading in Scala.

Local functions can be used in Scala

Java's anonymous inner classes are needed to implement local functions(nested scopes) in Java. Scala, being a functional programming language supports closures and lambda functions in a natural way.

Having nested functions with local scope, also reduces the need for private methods that may have be declared just to be used with one method.

REPL

Scala can be used as an interpreted language by invoking the Scala REPL. Programmers used to scripting languages that come with a REPL can relate to the power such a tool. In Java, I would find it very difficult to prototype small classes or expressions, since they need detailed class definitions and compilation. Whereas, using Scala you can evaluate expressions, declare and use classes on the command line as you go. This alone should be a powerful motivator to try out Scala.

You could get the taste of it here

And yes, Look Ma, no semi-colons

I just could live without it, and I am sure you too would agree.

Conclusion

The above facts are a very small subset on how Scala can add to a tool set of a Java programmer who might only been exposed to imperative style of programming. Scala's other strong OO features include the concepts of Trait, type parameterization and pattern matching. I hope to write about them in my future blog.

Scala, primarily was created to be 'scalable' language as well. It provides constructs for concurrent operations while abstracting away the locking mechanisms and the accompanying problems that plague such implementations.

For the functional programmer, I have not done justice to the power of Scala in this list. But, this list is strictly to encourage folks to start using Scala by having an extending tool-set when compared to Java.

Some of the functional aspects, I plan to talk about later on would be the powers that come with functional programming. Higher order functions, currying, abstracting control structures etc would fit that list.

I believe Scala given its pragmatic approach is on its way to earlier adoption when compared to other languages that compile to JVM. For me, it is just the good part of C# I missed in Java plus the functional part I could leverage while still utilizing legacy Java libraries and extending current Java projects that sound very promising.

Sources: