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.