As I understand it, in Scala, a function may be called either
- by-value or
- by-name
For example, given the following declarations, do we know how the function will be called?
Declaration:
def f (x:Int, y:Int) = x;
Call
f (1,2)
f (23+55,5)
f (12+3, 44*11)
What are the rules please?
In the case of your example all the parameters will be evaluated before it's called in the function , as you're only defining them by value. If you want to define your parameters by name you should pass a code block:
This way the parameter
x
will not be evaluated until it's called in the function.This little post here explains this nicely too.
I don't think all the answers here do the correct justification:
In call by value the arguments are computed just once:
you can see above that all the arguments are evaluated whether needed are not, normally
call-by-value
can be fast but not always like in this case.If the evaluation strategy was
call-by-name
then the decomposition would have been:as you can see above we never needed to evaluate
4 * 11
and hence saved a bit of computation which may be beneficial sometimes.The example you have given only uses call-by-value, so I will give a new, simpler, example that shows the difference.
First, let's assume we have a function with a side-effect. This function prints something out and then returns an
Int
.Now we are going to define two function that accept
Int
arguments that are exactly the same except that one takes the argument in a call-by-value style (x: Int
) and the other in a call-by-name style (x: => Int
).Now what happens when we call them with our side-effecting function?
So you can see that in the call-by-value version, the side-effect of the passed-in function call (
something()
) only happened once. However, in the call-by-name version, the side-effect happened twice.This is because call-by-value functions compute the passed-in expression's value before calling the function, thus the same value is accessed every time. However, call-by-name functions recompute the passed-in expression's value every time it is accessed.
Going through an example should help you better understand the difference.
Let's definie a simple function that returns the current time:
Now we'll define a function, by name, that prints two times delayed by a second:
And a one by value:
Now let's call each:
The result should explain the difference. The snippet is available here.