Scala Basics

Work in progress
Previous slide : 1- Introduction to scala and Functional Programming

Scala console


scala> 1+1
res0: Int = 2

scala> res0 + 3
res1: Int = 5

scala> val a = res1 * 10
a: Int = 50

scala> math.sqrt(a)
res2: Double = 7.0710678118654755

Values

scala> val a = 1 // you can declare a variable without a type
a: Int = 1

scala> val b:Int = 1 // Specifying return type is not required
b: Int = 1

scala> val c:Double = 1.5
c: Double = 1.5

scala> val d:Double = 1 // It will cast types if possible (Int->Double)
d: Double = 1.0

scala> val e:Int = 1.5 // If it cannot cast it returns with an error
<console>:11: error: type mismatch;
 found   : Double(1.5)
 required: Int
       val e:Int = 1.5
                   ^

Values


scala> val i = 10
i: Int = 10

scala> i = 4
<console>:12: error: reassignment to val
       i = 4
         ^

Values : A value cannot be reassigned.
It is similar to Java's Final variable.
But they can be overridden in a sub class.

Variables


scala> var j = 10
j: Int = 10

scala> j=4
j: Int = 4

If you need to change the value then you can use a var instead.

Types of Types

Any Type

Class Any is the root of the Scala class hierarchy. Every class in a Scala execution environment inherits directly or indirectly from this class. Class Any has two direct subclasses: AnyRef and AnyVal.


                    
scala> var a:Any = 1
a: Any = 1

scala> a = "hey"
a: Any = hey

scala> a = 0.0
a: Any = 0.0

scala> a = new util.R
Random   Right

scala> a = new util.Random(123)
a: Any = scala.util.Random@54689939
                    
                

Method invocation

scala> def foo(x:Int=1,y:Int=2) = x+y
foo: (x: Int, y: Int)Int

foo() // Function has predefined default Values
foo(5) // Replaces x with 5, and the default value for y
foo(1,4) // Both parameters are passed
foo(y=6) // Named parameter for y, x takes on the default parameter
foo(x=4,y=6) // Named parameter
foo(y=14,x=6) // Order of the named parameter can be of any order
foo(4,y=2)

scala> def returnFalse() = false
returnFalse: ()Boolean

returnFalse() // Returns false
returnFalse // Also returns false, you can avoid parenthesis

foo // Try this one out ?

Suffix Notation

Scala allows methods of arity-0 to be invoked using suffix notation:


scala> val names = "Vishnu,Prasad,Suresh,Ravi" split ","
names: Array[String] = Array(Vishnu, Prasad, Suresh, Ravi)

names.toList
// is the same as
names toList // Unsafe, don't use!

//This style is unsafe, and should not be used.
//Since semicolons are optional,
//the compiler will attempt to treat it as an infix method if it can,
//potentially taking a term from the next line.

names toList
val answer = 42        // will not compile!
                    
Apply Method

Apply methods give you a nice syntactic sugar for when a class or object has one main use.


scala> class Foo {
     |   def apply() = 0
     | }
defined class Foo

scala> object FooMaker {
|   def apply() = new Foo
| }
defined module FooMaker

scala> val newFoo = FooMaker()
newFoo: Foo = Foo@5b83f762

scala> newFoo()
res8: Int = 0
scala> val a = Array(1,2,3)
a: Array[Int] = Array(1, 2, 3)

scala> a(1)
res5: Int = 2

scala> val b = Map(1->"One",2->"Two")
b: scala.collection.immutable.Map[Int,String] = Map(1 -> One, 2 -> Two)

scala> b(1)
res3: String = One

scala> b(2)
res4: String = Two
Control Structures

If Statement


if (condition)
    //Sucess Block
else
    //Failure Block

val a = 10
val b= 13
if(a>b) {
    println(a+" is greater")
} else {
    println(b+" is greater")
}

if(a>b) println(a+" is greater") else println(b+" is greater")

If Statement

scala> def abs(x: Int): Int = if (x > 0) x else -x
abs: (x: Int)Int

scala> abs(-10)
res14: Int = 10

scala> val x = 10
x: Int = 10

scala> val absoluteX = if (x > 0) x else -x
absoluteX: Int = 10

scala> val y = -10
y: Int = -10

scala> val absoluteY = if (y > 0) y else -y
absoluteY: Int = 10

For Loop

for ( var x <- Range) {
  //Code Block
}

for (x <- 1 to 10) {
  println("Value of x: " + x)
}

val (a, b) = (1 to 5).map(i => (i, i*10)).toArray.unzip

for(x<-a;y<-b){
  println(x,y)
}

For Loop with Yield


for {
  x <- a
} yield x

for {
  x <- a
  y <- b
} yield (x,y)

for {
  x <- a
  y <- b
} yield (x,y,x<y)

For further Reading on Yield checkout : How does yield work?

While Loop


while(condition){
   statement(s);
}

var i = 0
while (i < 20) {
  println("Value of i: " + i)
  i = i + 1
}

while (true) {
  println("Infinite Loop")
}
        

Note: Never omit braces (while cannot be used in a pure-functional manner).

Pattern Matching


x match {
  case value => { //Code Block }
  case value => { //Code Block }
  case _ => { //Default Code Block }
}

x match {
  case _:Type => { //Code Block }
  case _:Type => { //Code Block }
  case _ => { //Default Code Block }
}
        

Scala has a built-in general pattern matching mechanism. It allows to match on any sort of data with a first-match policy.

Pattern Matching

x match {
  case "One" => 1
  case "Two" => 2
  case _ => 0
}

x match {
  case _: String => x.asInstanceOf[String]
  case _: Double => x.asInstanceOf[Double].toString
  case _ => x.toString
}

x match {
  case v: String => v.toString
  case v: Double => v.toString
  case v => v.toString
}

Thank you


Next Slide : 3- Scala-collections