Why must forward referenced values inside blocks in Scala be lazy? -
the scope of name introduced declaration or definition whole statement sequence containing binding. however, there restriction on forward references in blocks: in statement sequence
s[1]...s[n]
making block, if simple name ins[i]
refers entity defineds[j]
j >= i
,s[k]
between , includings[i]
,s[j]
,
s[k]
cannot variable definition.- if
s[k]
value definition, mustlazy
.
edit: not sure mikaël mayer's answer explained everything. consider:
object test { def main(args: array[string]) { println(x) lazy val x: int = 6 } }
here, lazy value x
has read/evaluated before defined in code! contradict mikaël's claim lazy evaluation away need evaluate things before defined.
normally 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 not yet defined @ time of definition of a. because references c, values between , c should lazy dependency 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 , c objects value initialized when read, after declaration, i.e. equivalent to:
val e: int = 2 var a: lazyeval[int] = null var b: lazyeval[int] = null var c: lazyeval[int] = null = 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
following (implemented compiler itself)
class lazyeval[t] { var value: t = _ var computed: boolean = false def evalinternal(): t // abstract method overriden def eval(): t = { if(computed) value else { value = evalinternal() computed = true value } } }
edit
vals don't exist in java. local variables or not exist in computation. therefore, declaration of lazy val exists before done. , remember closures implemented in scala. block rewritten it:
object test { def main(args: array[string]) { // declare variables, val, vars. var x: lazy[int] = null // no more variables declare. lazy/or not variable definitions x = new lazyeval[int] { def evalinternal() = 6 } // code starts println(x) } }
Comments
Post a Comment