Normally you cannot have this:

val e: Int = 2 val a: Int = b+c val b: Int = c val c: Int = 1 val d: Int = 0

because value c is not yet defined at the time of the definition of a. Because a references c, all values between a and c should be lazy so that the dependency is avoided

val e: Int = 2 lazy val a: Int = b+c lazy val b: Int = c lazy val c: Int = 1 val d: Int = 0

This in fact translates a, b and c as objects whose value is initialized when it is read, which would be after the declaration, i.e. this would be equivalent to:

val e: Int = 2 var a: LazyEval[Int] = null var b: LazyEval[Int] = null var c: LazyEval[Int] = null a = new LazyEval[Int] { def evalInternal() = b.eval() + c.eval() } b = new LazyEval[Int] { def evalInternal() = c.eval() } c = new LazyEval[Int] { def evalInternal() = 1 } val d = 0

where LazyEval would be something like the following (implemented by the compiler itself)

class LazyEval[T] { var value: T = _ var computed: Boolean = false def evalInternal(): T // Abstract method to be overriden def eval(): T = { if(computed) value else { value = evalInternal() computed = true value } } }

Edit

vals don't really exist in java. They are local variables or do not exist in computation. Therefore, the declaration of lazy val exists before anything is done. And remember that closures are implemented in Scala. Your block would be rewritten as it:

object Test { def main(args: Array[String]) { // Declare all variables, val, vars. var x: Lazy[Int] = null // No more variables to declare. Lazy/or not variable definitions x = new LazyEval[Int] { def evalInternal() = 6 } // Now the code starts println(x) } }