I understand the basic concept of call-by-name and call-by-value, and I have also looked into handful number of examples. However, I am not very clear about when to use call-by-
Call by name means the value is evaluated at the time it is accessed, while with call by value the value is evaluated first and then passed to the method.
To see the difference, consider this example (completely non-functional programming with only side effects ;) ). Say you want to create a function which measures how much time some operation takes. You can do it with call-by-name:
def measure(action: => Unit) = {
println("Starting to measure time")
val startTime = System.nanoTime
action
val endTime = System.nanoTime
println("Operation took "+(endTime-startTime)+" ns")
}
measure {
println("Will now sleep a little")
Thread.sleep(1000)
}
You will get the result (YMMV):
Starting to measure time
Will now sleep a little
Operation took 1000167919 ns
But if you change only the signature of measure
to measure(action: Unit)
so it uses pass-by-value, the result will be:
Will now sleep a little
Starting to measure time
Operation took 1760 ns
As you can see, the action
is evaluated before measure
even starts and also the elapsed time is close to 0 due to the action already having been run before the method was called.
Here, pass-by-name allows the expected behavior of the method to be achieved. In some cases it doesn't influence the correctness, but does influence the performance, for example in logging frameworks where a complex expression might not need to be evaluated at all if the result is not used.