Evaluation strategies are used by programming languages to determine when to evaluate the argument(s) of a function call, the common evaluation strategy are call-by-name and call-by-value, and we have call-by-reference even.

What is call-by-value ?

In call by value, the argument expression is evaluated, and the resulting value is bound to the corresponding variable in the function,by copying the result in to new memory location,so let see the example in scala and basic detail how it works

 
 def printSomething(input:Any):Unit = {
    println(input)
    Thread.sleep(100)
    println(input)
  }
  
  printSomething(System.currentTimeMillis());

**Console output is **

1533720102286
1533720102286

The above function takes the Any type as input parameter, when we are doing the function call like printSomething(System.currentTimeMillis());
In call by value fashion System.currentTimeMillis() is first evaluated and assigned to input parameter so technically out function call will be like this printSomething(1533720102286)

What is Call-by-name ?

Call by name is an evaluation strategy where the arguments to a function are not evaluated before the function is called rather, they are substituted directly into the function body,they will evaluated where ever the parameter is used in the function body as in need.o let see the example in scala and basic detail how it works

 def printSomething(input: =>Any):Unit = {
    println(input)
    Thread.sleep(100)
    println(input)
  }

 printSomething(System.currentTimeMillis());

Console output is

1533721159821
1533721159933

So in the Above example console output of both lines were identical, but here we have difference in the time stamp value,so the execution of program will be like this

 def printSomething(input: =>Any):Unit = {
    println(System.currentTimeMillis())
    Thread.sleep(100)
    println(System.currentTimeMillis())
  }

Instead of having value,System.currentTimeMillis() is evaluated in each println statement