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 in s[i] refers entity defined s[j] j >= i, s[k] between , including s[i] , s[j],

  • s[k] cannot variable definition.
  • if s[k] value definition, must lazy.

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

Popular posts from this blog

android - Get AccessToken using signpost OAuth without opening a browser (Two legged Oauth) -

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: mockito -

google shop client API returns 400 bad request error while adding an item -