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 Objects – Yes 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 Scala - http://scala-lang.org/download/
Download Typesafe Reactive Platform for Scala - http://typesafe.com/platform/getstarted
Scala IDE for Eclipse - http://scala-ide.org/
Scala documentation - http://www.scala-lang.org/documentation/
Scala school - http://twitter.github.io/scala_school/
Scala tutorial - http://docs.scala-lang.org/tutorials/
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.