Try   HackMD

Lazy keyword in Scala

Today we are going to talk about the lazy keyword in Scala.
First, let's talk about what lazy is. It does what it name says it puts off some work until you need it which means the lazy expression is evaluated at most once, namely the first time the value is used. if it's never used, it will never be evaluated.
To demonstrate, let's define an expensive calculation which takes no parameters and returns a Long value.

def expensive: Long = {
  println("Hello")
  Thread.sleep(500)
  2020
}

expensive 
// Hello
// res0: Long = 2020

expensive
// Hello
// res1: Long = 2020

The implementation is a code block in which we first print "Hello" to standard out, sleep, and then return the value. We do this to simulate a computation that takes a long time a computation we would like to avoid if it's not needed.
Defining this method returns immediately because we haven't called it yet.
If we call the method twice, we'll see that each time the method call takes about 500 milliseconds, and each time our log statement appears. That's because the code block on the right side of the function definition is evaluated every time.
Let's change this behavior by using a lazy val. The following example will illustrate this by copying the previous example and changing the def to the lazy val:

lazy val lazyExpensive: Long = {
  println("Hello")
  Thread.sleep(500)
  2020
}

lazyExpensive
// Hello
// res2: Long = 2020

lazyExpensive
// res3: Long = 2020

As the output shows, the expression assigned to LazyExpensive is lazy and has not been evaluated yet.
When we access the value for the first time, we see that the evaluation takes place. Our log statement is printed out and we have to wait for about 500 milliseconds. A subsequent use of the lazyExpensive value does not require a new evaluation of the expression, so the second time we access it in the example, the value 2020 is returned immediately.
You can use the lazy modifier for any val, whether it is a local one or defined only inside of a function or a field of a class or object.

You should be aware that lazy is not for free. Unlike a strictly evaluated val or a parameterless function defined with def a lazy val requires synchronization, because the semantics of evaluating the right-side expression at most once must also be guaranteed if multiple threads try to use that value concurrently. Hence, it would be best if you considered whether you need the call-by-need semantics or by-name or by-value evaluation is fine as well in a particular case.