Friday, 10 March 2017

Variables / Arguments evaluation rules in Scala


Evaluation Rules in Scala

Call by Value: Evaluates the function arguments before calling the function

Call by Name: Evaluates the function first and then evaluates the arguments



def example = 2 // evaluated when called
val example = 2 //evaluated immediately
lazy val example = 2 //evaluated once when needed
def square(x: Double) // call by value def square(x: => Double) // call by name def myFct(bindings: Int*) = { ... } // bindings is a sequence of int,
// containing a varying # of arguments

Scala fold diffrence foldLeft FoldRight , fold v/s foldLeft

What is the difference between fold, folRight, foldLeft in Scala?


Scala provides provides 3 methods to iterate the collection, namely fold, foldLeft and foldRight.

The differences between the three methods is very subtle, and is very simple to understand when we start with analyzing the signature of these 3 functions. 

The signature has 2 things in common:
1) Seed value or the initial value is required for the methods
2) An function/operation is needed, which accepts 2 arguments and returns the same type as the seed value.

Now to understand the differences between these methods lets look at individual signatures.

fold

def fold[A1 >: A](z: A1)(op: (A1, A1) ⇒ A1): A1

The input arguments to the op function is of same type, so fold method always requires
initial value to be of the same type as the collection content.

As we are aware the 3 methods are used to iterate the collections, fold is capable of
arbitrary tree decompositions on the sequential collection. In simple words the operation
specified for fold can execute in Parallel.


val list: List[Int] = List(1, 2, 3, 4, 5)
list.fold(0)(_ + _) // op function takes 2 Int and returns sum(Int)
// possible orders of parallel execution for fold
0 + 1 = 1 0 + 2 = 2 0 + 4 = 4 // 1st parallel operation
1 2 + 3 = 5 4 + 5 = 9 // 2nd parallel operation
1 5 + 9 = 14
1 + 14 = 15



foldLeft

def foldLeft[B](z: B)(op: (B, A) ⇒ B): B

The input arguments to the operation could possibly be of different types,
and one argument must be of the collection content type.

foldLeft sequentially access the collection elements one-by-one from Left to Right.



val list: List[Int] = List(1, 2, 3, 4, 5)
list.foldLeft(0)(_ + _)
// Only possible iteration sequence
0 + 1 = 1
1 + 2 = 3
3 + 3 = 6
6 + 4 = 10
10 + 5 = 15

foldRight


def foldRight[B](z: B)(op: (A, B) ⇒ B): B

foldRight is same as foldLeft except for the access order.

foldRight sequentially access the collection elements one-by-one from Right to Left.


val list: List[Int] = List(1, 2, 3, 4, 5)
list.foldRight(0)(_ + _)
// Only possible iteration sequence, Reverse access to elements
0 + 5 = 5
5 + 4 = 9
9 + 3 = 12
12 + 2 = 14
14 + 1 = 15