The following are both meant to create a Stream of integers:
val s: Stream[Int] = 1 #:: s.map(_ + 1)
def makeStream = {
val s: Stream[Int] = 1 #:: s.map(_ + 1
Inside a class, a val
definition decompiles into an "getter" method that references a hidden class field. These "getter" methods can be self-referential (or rather, the class initializer can reference the "getter") because this is the semantics of Java methods. Note that your "outside" definition of val s
is actually wrapped in a hidden class by the REPL (this is how the REPL circumvents the restriction that a val
can't be declared at the top level).
Inside a method, the val
definition does not decompile into a "getter" method, but rather into the bytecode necessary to generate a value on the stack. A lazy val
, on the other hand, always requires a "getter" method which, as such, can be self-referential.