Say, first, I have this function:
def number5()={
println("number 5 starting")
println("number 5 exiting")
5
}
And then:
def giveMeCallByNameParameter(f: =>Int)={
println("starting")
f
println("exiting")
}
When I call it:
giveMeCallByNameParameter(number5)
I get this result:
starting
number 5 starting
number 5 exiting
exiting
And if I also have this function:
def giveMeAnotherFunction(f: ()=>Int)={
println("starting")
f()
println("exiting")
}
And I call it:
giveMeAnotherFunction(number5)
I get the same result:
starting
number 5 starting
number 5 exiting
exiting
So, are they different at all? Other than the difference of having or not having the parenthesis?
If they are not different? Then why do we have this terminology call by name?
By-name parameters can be any valid expression. Functions are also valid expressions, but just one kind of expression.
The big difference between by-name parameters and by-value parameters is that by-value parameters, the most common kind of function parameter, are evaluated before being passed into the function. By-name parameters' evaluation is delayed until at least after being passed into the function. The function itself may or may not evaluate the parameter, it is not obligated to.
It just so happens that functions have this same kind of property, but again, as I said earlier, functions are just one kind of expression, whereas by-name parameters can take any kind of valid expression.
A great use case for a by-name parameters is in building a custom assert function:
def byNameAssert(predicate: => Boolean) =
if (assertionsEnabled && !predicate)
throw new AssertionError
This way, you could turn off the evaluation of asserted conditions by controlling the assertionsEnabled
value.
If assertions aren't enabled, you could even have an expression, which would ordinarily throw, not yield an exception:
byNameAssert(x / 0 == 0)
Also note well that the expression, x / 0 == 0
, is not a function! By-name parameters can take any kind of expression but will defer their evaluation until at least after the function is called.
Hope this helps!