I'm learning scala and I have come across the following code.
def whileLoop(cond: => Boolean)(body: => Unit): Unit =
if (cond) {
body
whileLoop(cond)(body)
}
var i = 10
whileLoop (i > 0) {
println(i)
i -= 1
}
The output is the numbers 10 to 1.
So both cond and body are "call by name" parameters. Which means they are evaluated when used in the function. If I understand that correctly. What I don't understand is how the body
println(i)
i -= 1
changes for each level of recursion that is applied the body is changing as the variable i is changing. But how does that exactly work? Each time the same function body is passed, to me this function stays the same but running the program shows me otherwise. I know that the function is evaluated each time but I don't understand how the i variable inside changes each time so can someone explain me how that works?
In this example, the body
is a closure that operates on the variable
iwhich is in the scope of the body's definition. Henceiis not a local variable of the body, meaning that the operation-=modifies the only existing valuei, not a local copy that gets discarded after the method invocation.The same is true for the condition: It is a closure that captures the same variable
i, hence after each execution of the body, the condition will see the now updated value ofi.Let us rewrite the example slightly without altering the meaning: Firstly, we can rewrite the
whileLoopto take functions as arguments instead of call-by-name parameters:This rewritten
whileLoopis semantically identical since a call-by-name argument is passed as an expression instead of the expression's evaluation. Disclaimer: I do not know if there are technical differences, e.g., regarding performance.Secondly, we can make the expressions that are passed for
condandbodyfunctions that take no argument:Since both of them reference the variable
ithat is neither part of their parameters nor defined inside their body, we must putiin their scope.So
iis accessible from both,condDefandbodyDefand is accessed and modified when they are evaluated.