Search code examples
scalalazy-evaluation

What does a lazy val do?


I noticed that Scala provide lazy vals. But I don't get what they do.

scala> val x = 15
x: Int = 15

scala> lazy val y = 13
y: Int = <lazy>

scala> x
res0: Int = 15

scala> y
res1: Int = 13

The REPL shows that y is a lazy val, but how is it different from a normal val?


Solution

  • The difference between them is, that a val is executed when it is defined whereas a lazy val is executed when it is accessed the first time.

    scala> val x = { println("x"); 15 }
    x
    x: Int = 15
    
    scala> lazy val y = { println("y"); 13 }
    y: Int = <lazy>
    
    scala> x
    res2: Int = 15
    
    scala> y
    y
    res3: Int = 13
    
    scala> y
    res4: Int = 13
    

    In contrast to a method (defined with def) a lazy val is executed once and then never again. This can be useful when an operation takes long time to complete and when it is not sure if it is later used.

    scala> class X { val x = { Thread.sleep(2000); 15 } }
    defined class X
    
    scala> class Y { lazy val y = { Thread.sleep(2000); 13 } }
    defined class Y
    
    scala> new X
    res5: X = X@262505b7 // we have to wait two seconds to the result
    
    scala> new Y
    res6: Y = Y@1555bd22 // this appears immediately
    

    Here, when the values x and y are never used, only x unnecessarily wasting resources. If we suppose that y has no side effects and that we do not know how often it is accessed (never, once, thousands of times) it is useless to declare it as def since we don't want to execute it several times.

    If you want to know how lazy vals are implemented, see this question.