By-name parameters are evaluated whenever they are called. They are never evaluated if unused inside the function body.
So, the argument is not evaluated at the point of function application but instead is evaluated at each use within the function.
To make an argument called by-name, we prepend it by =>
.
def compute(id: =>Int) = id*100
Packages are created by declaring package names at the top of the program file.
In contrast to call by-name, arguments called by-value are evaluated only once, and they are the default calling method in Scala.
In the following function addTwo
, since x
is called by-value, it will be evaluated first in the expression 3+4 as 7 in line 2, and then passed into the function body where it is added to itself:
def addTwo(x:Int, y: => Int) = x+xprintln(addTwo(3+4, 7))println(addTwo(8,3+5))
On the other hand, in line 3, using the call-by name strategy, the expression 3+5 is never evaluated as y
is not used in the function body. Therefore, in this example, the call-by name strategy is one step ahead. Let’s further explore this with a program that performs infinite computation:
def addTwo(x:Int, y: => Int) = x+xdef infinite():Int = 2 + infinite()println(addTwo(4, infinite))//println(addTwo(infinite,4))
In the example above, infinite
is a recursive function which calls itself infinitely. When we pass the function infinite
as the y
argument, the output is calculated as shown in line 3. This is because y
is never used in the function body, and the infinite
function is never called.
However, if you comment out line 4, you will see a StackOverFlow error as the infinite function is called by-value, so it is evaluated first before being used in the function. Here, we can observe the advantage of by-name parameters because it helps performance in scenarios where the parameter is computationally expensive.
Free Resources