This page is no longer maintained — Please continue to the home page at www.scala-lang.org

lazy val

6 replies
normen.mueller
Joined: 2008-10-31,
User offline. Last seen 3 years 8 weeks ago.

He,

I wonder if "lazy" values are re-computed every access call. For
example,

class A {
lazy val foo = {
// some complex computations
}

val a = new A
println(a.foo)
println(a.foo)

I debugged the complex computation of "foo" and was surprised that my
breakpoint within in the "foo" computation got called again in the
second "println(a.foo)".

What am I missing here?

Cheers,
--
Normen Müller

Jorge Ortiz
Joined: 2008-12-16,
User offline. Last seen 29 weeks 3 days ago.
Re: lazy val
You can see for yourself with the interpreter

scala> class A {
     |   lazy val foo = {
     |     println("Defining foo")
     |     (new scala.util.Random).nextInt
     |   }
     | }
defined class A

scala> val a = new A
a: A = A@2fba32e3

scala> println(a.foo)
Defining foo
-1824690572

scala> println(a.foo)
-1824690572

No clue why your breakpoints are getting triggered.

--j

On Tue, Jan 20, 2009 at 1:31 AM, Normen Mueller <normen [dot] mueller [at] googlemail [dot] com> wrote:
He,

I wonder if "lazy" values are re-computed every access call.  For example,

class A {
 lazy val foo = {
   // some complex computations
 }

val a = new A
println(a.foo)
println(a.foo)

I debugged the complex computation of "foo" and was surprised that my breakpoint within in the "foo" computation got called again in the second "println(a.foo)".

What am I missing here?

Cheers,
--
Normen Müller




normen.mueller
Joined: 2008-10-31,
User offline. Last seen 3 years 8 weeks ago.
Re: lazy val

On Jan 20, 2009, at 10:44 AM, Jorge Ortiz wrote:
> You can see for yourself with the interpreter
>
> scala> class A {
> | lazy val foo = {
> | println("Defining foo")
> | (new scala.util.Random).nextInt
> | }
> | }
> defined class A
>
> scala> val a = new A
> a: A = A@2fba32e3
>
> scala> println(a.foo)
> Defining foo
> -1824690572
>
> scala> println(a.foo)
> -1824690572
>
> No clue why your breakpoints are getting triggered.

Very good explanation! Thank you very much!

Cheers,
--
Normen Müller

Luc Duponcheel
Joined: 2008-12-19,
User offline. Last seen 34 weeks 3 days ago.
Re: lazy val
Scala defines a singleton object, say Anonymous, which has foo as a member, and evaluates Anonymous.foo.
When using the lazy value foo, the definition of foo is not evaluated any more.

Note that, when defining the parameterlistless function foo, the definition of foo is not evaluated.
Scala defines a singleton object, say Anonymous, which has foo as a member.
When using the parameterlistless function foo, the definition of foo is evaluated.

--
  __~O
 -\ <,
(*)/ (*)

reality goes far beyond imagination

Blair Zajac
Joined: 2009-01-12,
User offline. Last seen 42 years 45 weeks ago.
Re: lazy val

Luc Duponcheel wrote:
> FYI: try the following
>
> scala> lazy val foo = { println("evaluating") ; "foo" }
> evaluating
> foo: java.lang.String = foo
>
> scala> def bar = { println("evaluating") ; "bar" }
> bar: java.lang.String
>
> scala> foo
> res0: java.lang.String = foo
>
> scala> bar
> evaluating
> res1: java.lang.String = bar
>
> Note that, when /defining/ the lazy value foo, the definition of foo
> /is/ evaluated.
> Scala defines a singleton object, say Anonymous, which has foo as a
> member,/ and/ evaluates Anonymous.foo.
> When /using/ the lazy value foo, the definition of foo /is not/
> evaluated any more.

The lazy val foo is being shown as evaluated because the scala shell is using
toString on the value to print it, so it is being evaluated. I think a better
example is to show this:

scala> class Foo { lazy val foo = { println("evaluating") ; "foo" } }
defined class Foo

The foo isn't being evaluated when it is defined.

Blair

Blair Zajac
Joined: 2009-01-12,
User offline. Last seen 42 years 45 weeks ago.
Re: lazy val

Normen Mueller wrote:
> He,
>
> I wonder if "lazy" values are re-computed every access call. For example,
>
> class A {
> lazy val foo = {
> // some complex computations
> }
>
> val a = new A
> println(a.foo)
> println(a.foo)
>
> I debugged the complex computation of "foo" and was surprised that my
> breakpoint within in the "foo" computation got called again in the
> second "println(a.foo)".
>
> What am I missing here?

Run javap on the class and you'll see some code there to check if it has been
evaluated so the debugger can still break on it.

Blair

normen.mueller
Joined: 2008-10-31,
User offline. Last seen 3 years 8 weeks ago.
Re: lazy val

On Jan 20, 2009, at 5:40 PM, Blair Zajac wrote:
> Normen Mueller wrote:
>> He,
>> I wonder if "lazy" values are re-computed every access call. For
>> example,
>> class A {
>> lazy val foo = {
>> // some complex computations
>> }
>> val a = new A
>> println(a.foo)
>> println(a.foo)
>> I debugged the complex computation of "foo" and was surprised that
>> my breakpoint within in the "foo" computation got called again in
>> the second "println(a.foo)".
>> What am I missing here?
>
> Run javap on the class and you'll see some code there to check if it
> has been evaluated so the debugger can still break on it.

That sounds reasonable! Thank you all for your help and confirmation
that I didn't understand "laziness" wrong ;-)

Cheers,
--
Normen Müller

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland