Search code examples
kotlinsyntaxlazy-evaluation

What does "lazy" mean with this code in Kotlin?


What is this code line doing?

fun<T:x>a.b(y: Int)=lazy{u.v<T>(y)}

I do not know what is 'lazy' doing or is 'lazy' something special in Kotlin.


Solution

  • fun<T:x>a.b(y: Int)=lazy{u.v(y)}

    Let's break this down. First, let's reformat for readability :)

    fun <T: x> a.b(y: Int) = lazy { u.v<T>(y) }

    Now, let's go piece by piece.

    fun means we're declaring a new method.

    <T:x> means this is a generic method operating on type T where T is constrained to be of type x.

    a.b means this is an extension function named b on type a.

    (y: Int) means that the defined function b takes a single argument named y of type Int.

    = is expression body syntax - shorthand for returning a short line of code. This means that a.b will return the value that is the result of evaluating lazy { }

    lazy is a Kotlin standard library function that delays the evaluation of the function provided to it until it's needed and then caches the result. The return value of this function is actually a type Lazy that wraps the provided function.

    { u.v<T>(y) } is the function that will be executed by the Lazy object when it's value is obtained the first time and the return value of u.v<T>(y) will be saved as the lazy object's value.

    Phew! So what does that mean? Let's look at an example. Suppose we add a print statement to the function to see when it's called.

    fun <T: x> a.b(y: Int) = lazy {
      println("Executing 'b'")
      u.v<T>(y)
    }
    

    Now if you tried to use it:

    fun main() {
      val a = A<T>() // Assume some type T
      val lazyObject = a.b<T>(42) // Call the extension method that returns a `Lazy`
      
      // Get the value from the lazy object - prints "Executing 'b'",
      // executes `u.v<T>(y)`, caches the result, returns it - then print it
      println(lazyObject.value) 
     
      // Get the value from the lazy object again. This time, DOES NOT print
      // "Executing 'b'", DOES NOT execute `u.v<T>(y)`, and just returns the
      // result that was already computed and cached, then print it
      println(lazyObject.value)  
    }
    

    So, in summary, the code you posted is creating an extension method that returns a Lazy object that, when queried for its value, executes the lambda it's initialized with and caches that result for later use.

    Hope that helps!