Sunday, December 08, 2013

Emerging languages series - Scala



Although my experience in Scala language is limited but in last couple of weeks have read a lot about Scala and its growth over recent years. Coming from Java background and recent demand for Scala has forced me to dig deeper to explore the potential and features of the language.

Scala overview  –
Scala is an acronym for “Scalable Language”. Scala is a statically typed, object oriented functional language, merging two popular programming approaches into one
In other words we can say when Object-Oriented meets Functional then the result is known as Scala. It was built by Martin Odersky at EPFL, launched in 2003.
Scala runs on the JVM. Java and Scala classes can be freely mixed, no matter whether they reside in different projects or in the same.
Java libraries, frameworks and tools are all available. Build tools like ant or maven, IDEs like Eclipse, IntelliJ, or Netbeans, frameworks like Spring or Hibernate all work seamlessly with Scala. Scala runs on all common JVMs and also on Android.
Already used by Twitter, LinkedIn, Yammer, Foursquare, eBay, Amazon , Guardian newspaper and many others

Key features of Scala language  – Scala has a set of features which differ from Java. Some of these are:
All types are objects
Type inference
Functions are objects
Anonymous function
Curried function
Closures
Traits
Domain specific language (DSL) support
Concurrency support inspired by Erlang

Scala comes with an interactive interpreter, the REPL (for Read, Evaluate, Print Loop). After installing Scala, you can start the REPL by entering the command scala in a command prompt or shell window. Visit the Scala download page here. 

You can type statements and expressions at the prompt, and the REPL will evaluate these and print the results. The REPL is a useful tool for experimenting with Scala language features. The REPL understands a number of special commands that start with a colon. Type the command :help to see an overview. Type :quit to exit the REPL.

Compiling and running Scala code –
Before getting into any example please remember you can Compile Scala source files using the Scala compiler, scalac. When you use Scala as a compiled language your code must be organized a little differently than when using it as a scripting language. You’ll need to create a Scala object with a main method, as in the following example.

// HelloWorld.scala
object HelloWorld {
def main(args: Array[String]) {
 println(“Hello World!”)
}
}

Save this in a source file named HelloWorld.scala. Compile it with: scalac HelloWorld.scala and run it with: scala HelloWorld. Note that in this last command, you supply the name of the object (HelloWorld) rather than the name of the source file (HelloWorld.scala) or the compiled class file (HelloWorld.class).


Scala features By Example

Values and variables -
val name: Type = expression    // use to define an immutable value
var name: Type = expression   // use to define a mutable variable

val myVal : Int = 1;
var name = "Sajid"

Tuples -
Tuples are type-safe containers for multiple values. They useful if you want to return more than one value from a method. They are different from collections;
each element in a tuple has its own type, whereas in collections all elements in the collection usually have the same type.

// Defines a tuple with a String and an Int
val tup = (“Hello”, 123)
// The elements of a tuple are named _1, _2 etc.
println(tup._1)
println(tup._2)

// Method that returns a Tuple with two Ints
def div(a: Int, b: Int): (Int, Int) = (a / b, a % b)

// Call the method, use pattern matching to extract the values from the result, throw away the second value
val (x, _) = div(20, 7)


Methods
def name[TypeParams](ParamList1)(ParamList2)(...): ReturnType = {
// Statements and expressions
}

// Here you see return type is inferred and “return” keyword is optional
def add(x:Int, y:Int) = {
  x + y
println(add(42,13))


Default parameters
Parameters may have a default value that is used if a value is not supplied when calling the method.
def greet(name: String = “there”) {
println(“Hello “ + name)
}

Return multiple variables - It is possible to return multiple variables using Tuple
def swap(x:String, y:String) = (y, x) 
val (a,b) = swap("hello","world") 
println(a, b)


Functions –
The difference between a function and a method is that a function is a value (an object) while a method is not. A function is an instance of one of the traits Function0, Function1 etc., depending on the number of parameters that the function takes.

def add(a:Int, b:Int):Int = a + b
val m:Int = add(1, 2)
println(m)

You can convert a method to a function by assigning it to a val or var. However, to avoid ambiguity, you have to either explicitly specify the type of the val or var, or put an underscore after the method name to indicate that you want to treat it as a function.
// A method
def succ1(x: Int) = x + 1
// Explicitly specify the type of succ2
val succ2: Int => Int = succ1
// Or put an underscore after the method name
val succ2 = succ1 _


Higher order functions –
def identity(x: Int) = x
def sqr(x: Int) = x * x
def cube(x: Int) = x * x * x

def sum(f: Int=>Int, a: Int, b: Int): Int =
if (a == b) f(a) else f(a) + sum(f, a + 1, b)

println(sum(identity, 1, 10))
println(sum(sqr, 1, 10))
println(sum(cube, 1, 10))

"sum" is now a "higher order" function, It's first parameter is a function which maps an Int to an Int

The type "Int" represents a simple Integer value. The type Int => Int represents a function which accepts an Int and returns an Int.


Anonymous functions –
A method that requires a function as a parameter  the function's type is (Int,Int) => Int

def sum(f: Int=>Int, a: Int, b: Int): Int =
if (a == b) f(a) else f(a) + sum(f, a + 1, b)
println(sum(x=>x, 1, 3))
println(sum(x=>x*x, 1, 3))
println(sum(x=>x*x*x, 1, 3))

We can create "anonymous" functions on the fly. x => x*x is a function which takes an "x" and returns x*x


Curried functions –
Currying allows to turn a function that expects two arguments into a function that expects only one, and that function returns a function that expects the second argument. Creating basically a chain of functions.

def addA(x: Int, y: Int): Int =
x + y
def addB(x: Int):Int=>Int =
y => x + y
val a = addA(10, 20)
val b = addB(10)(20)
println(a)
println(b)

You can take any function of multiple arguments and curry it.


Traits –
trait Name[TypeParams] extends ClassOrTrait with Trait1 with Trait2 with ... {
// Constructor statements and trait members
}

A trait can extend one class and multiple other traits. A trait can have a constructor (you can put statements in the body of the trait that are executed as part of its constructor), but it cannot have constructor parameters.

Traits are like Java interfaces, except that a trait can be partially implemented. Like a Java interface, a trait cannot be directly instantiated even if it is fully implemented.

trait Car {
  val brand: String
}

trait Shiny {
  val shineRefraction: Int
}

One class can extend several traits using the with keyword:
class BMW extends Car with Shiny {
  val brand = "BMW"
  val shineRefraction = 12
}


Closure –
A "closure" is a function which carries with it references to the environment in which it was defined.
Alternately we can say that closure is a function, whose return value depends on the value of one or more variables declared outside this function. Consider the following piece of code with anonymous function

object Test {
   def main(args: Array[String]) {
      println( "muliplier(1) value = " +  multiplier(1) )
      println( "muliplier(2) value = " +  multiplier(2) )
   }
   var factor = 3
   val multiplier = (i:Int) => i * factor
}

Here  factor has a reference to a variable outside the function but in the enclosing scope.


Functions are ObjectsYes you read it correct J
Probably it might be little difficult to digest it if you coming from Java background. Don’t worry, here comes a golden rule of thumb. The key to scala is that everything is an object. Since every value is an Object in Scala, Functions are Objects, too!

Every Function you’ll ever define in Scala, will become an instance of an Implementation which will feature a certain Function Trait. There is a whole bunch of that Function Traits, ranging from Function1 up to Function22. Wow, and why are there so many? Since Functions are Objects in Scala and Scala is a statically typed language, it has to provide an appropriate type for every Function which comes with a different number of arguments. If you define a Function with two arguments, the compiler picks Function2 as the underlying type. If you define a Function with seven arguments, you’ll end up with Function7. And since there is a maximum up to Function22, that means you can’t define a Function which will accept 23 arguments or more.

new Function1[Int, Int] {
 def apply(x: Int): Int =
 x + 1
}


Patten matching –
Scala has a built-in general pattern matching mechanism. It allows to match on any sort of data with a first-match policy.
Here is a small example which shows how to match against an integer value:

object MatchTest1 extends Application {
  def matchTest(x: Int): String = x match {
    case 1 => "one"
    case 2 => "two"
    case _ => "many"
  }
  println(matchTest(3))
}

The block with the case statements defines a function which maps integers to strings. The match keyword provides a convenient way of applying a function (like the pattern matching function above) to an object.

Here is a second example which matches a value against patterns of different types:
object MatchTest2 extends Application {
  def matchTest(x: Any): Any = x match {
    case 1 => "one"
    case "two" => 2
    case y: Int => "scala.Int"
  }
  println(matchTest("two"))
}

The first case matches if x refers to the integer value 1. The second case matches if x is equal to the string "two". The third case consists of a typed pattern; it matches against any integer and binds the selector value x to the variable y of type integer.


Finally some of the key benefits of Scala –
  • Scala's case classes and pattern-matching make for very clean code, for example, and Scala traits (like interfaces with implemented methods) can be a very powerful and simple way to "inherit" behaviour without the pain of OO inheritance.
  • Scala's powerful type inference also combines the benefits of a strictly typed language with some of the benefits of dynamic typing in terms of having to write less code yourself.
  • Maintainability e.g. Scala code is often much more concise than Java (with all that boilerplate) and fewer LOC often means fewer places to screw up and less maintenance in the longer term.
  • Access to great Scala libraries e.g. for Collections, as well as to Java's existing libraries.
  • Scalability e.g through the use of Actors for (asynchronous) concurrency instead of threads, or through greater use of immutable data, functional programming etc.
  • Scala's hybrid ability to take advantage of FP and/or OOP as required for the task in hand.
Most people are using Scala on the server, because that's where you can gain the benefit of its scalability. Obviously, you can mix Scala with Java on a JVM server, and use your preferred client-side technology for browser interfaces etc. Scala is also the basis for version 2 of the lightweight Play! framework for web applications (although my understanding is that version 2.x is not currently Java EE compatible). My impression is that there is a growing trend towards looking at using the right language for specific purposes rather than a monolithic "one size fits all" approach.
Twitter is a prominent user and promoter of Scala, while LinkedIn also uses Scala for some applications.

Resources
Download Typesafe Reactive Platform for Scala - http://typesafe.com/platform/getstarted
Scala IDE for Eclipse - http://scala-ide.org/

Java 8 vs Scala: A Feature Comparison

Here’s a nicely written article on InfoQ which goes deep into this comparison and list out some of the key findings. Just to mention Java 8 is going to provide a variety of new language features, with the potential to fundamentally change the way we write applications. Especially the functional programming constructs, such as lambda expressions, can be considered a paradigm shift. This shift provides great new possibilities for more concise, compact and easy to understand code.
If you want to try them out then explore early builds of Java 8 on most platforms.

The best way to find out what a language can do for you is probably to try it out, and best way would be to sign up and learn about Functional Programming Principles In Scala from the language's creator Martin Odersky of EPFL at Coursera. Just check and register for any future date for free course.

Popular Posts