3

I have a val:

val something = System.nanoTime

that then goes through a series of method calls:

foo(something) {
  bar(something, 2) { etc }
}

I'd like to defer val resolution until a very last method that actually does something with it. I'm aware of scala's lazy modifier, but it seems that passing something as a parameter automatically resolves it's value, regardless if the variable is being used or not inside that method.

My (somewhat ugly) solution so far is:

val something = () => System.nanoTime

Although this works, it involves changing all the method signatures, in this case from Long to () => Long. I guess there might be a more elegant way of solving it, what do you guys think?

Pablo Fernandez
  • 103,170
  • 56
  • 192
  • 232

1 Answers1

6

It's not possible to do this without changing the signatures, however you should use x: => Long instead of x: () => Long. The first is a so called by name parameter. A by name parameter will be evaluated, every time you call it. So in total it would look like:

def foo(x: => Long) = {
  x + 12 // x will be evaluated here
}

lazy val x = 12L
foo(x)
Pablo Fernandez
  • 103,170
  • 56
  • 192
  • 232
drexin
  • 24,225
  • 4
  • 67
  • 81
  • 1
    The part with by-name-parameters is formulated improperly. They are executed each time they are called, in your description they look like being the same as a `lazy val`. – kiritsuku Sep 12 '12 at 16:23
  • 1
    Cf https://issues.scala-lang.org/browse/SI-240 or http://stackoverflow.com/questions/9809313/scalas-lazy-arguments-how-do-they-work – som-snytt Sep 13 '12 at 06:46