I was reading the section "Call-by-Name" in the book "Begining Scala" by David Pollak,
trying to get my head around by-name parameters. He gave an example,
def nano() = { println("Getting nano") System.nanoTime } def delayed(t: => Long) = { // => indicates a by-name parameter println("In delayed method") println("Param: "+t) t } println(delayed(nano()))
Coming from Java and used to call-by-reference, I was expecting the output to be
Getting nano In delayed method Param: 4513758999378 4513758999378 // same value as Param
but the output was
In delayed method Getting nano Param: 4475258994017 Getting nano 4475259694720 // different value from Param
Re-reading that section a couple of times still doesn't ring a bell (the book is really good though).
Googling "scala by-name parameters" returns long examples and explanations
on the subject, and more confusion for an absolute Scala beginner like me.
Referring to the Scala Language Specification, section 4.6.1 By-Name Parameters finally defreezes my brain.
... argument is not evaluated at the point of function application, but instead is evaluated at each use within the function.
Ok. Got it. Back to the example,
def delayed(t: => Long) = { println("In delayed method") println("Param: "+t) // t or nano() used, so "Getting nano" printed, // then print "Param: " and the return of nano(), e.g. System.nanoTime t // t or nano() used again, thus print "Getting nano" and the System.nanoTime // would have now elapsed }
Nice example, helped me a lot. Thx
ReplyDelete