Call by Name or Value in Scala

Call by Name or Value in Scala

This post is part 5 of the Scala - The Absolute Basics series. You can view all the posts in the series here.

There are two ways of calling functions in Scala, either call by name or call by value. Let’s dive straight into an example so that we can examine the difference:

  def calledByValue(x: Long): Unit = {
    println("by value: " + x)
    println("by value: " + x)
  }

  def calledByName(x: => Long): Unit = {
    println("by name: " + x)
    println("by name: " + x)
  }

These two functions are almost identical, apart from one key difference. The calledByName function has an arrow => inside the function definition.

So what exactly is the difference between these two functions? Well let’s call them both and see what we get back:

  calledByValue(System.nanoTime())
  calledByName(System.nanoTime())

And this is what we get back:

by value: 179116115013686
by value: 179116115013686
by name: 179116233824542
by name: 179116233862264

Call By Value

In the Call by Value function, the exact value of the expression is computed before the function evaluates. That same value then gets used in the function definition, and the same value is used everywhere in the function. The calledByValue function would technically look like this:

  def calledByValue(x: Long): Unit = {
    println("by value: " + 179116115013686L)
    println("by value: " + 179116115013686L)
  }

  calledByValue(179116115013686L)

This is most likely the style of calling parameters familiar to you if you are used to imperative programming languages like Java.

Call By Name

For the Call By Name function, the expression is passed to the function literally as it is. The expression then gets evaluated every time it is called inside the function. Our function then might look like this:

  def calledByName(x: => Long): Unit = {
    println("by name: " + System.nanoTime())
    println("by name: " + System.nanoTime())
  }

This is why, in our example, we see two different values when we print out the value of the function twice. The => arrow delays the evaluation of the expression passed as a parameter. The parameter is used literally every time when it is called in the function.

Another Example - Delay Evaluation

Let’s look at another example to illustrate this point. Say you had two functions as follows:

  def infinite(): Int = 1 + infinite()
  def printFirst(x: Int, y: => Int) = println(x)

If we called printFirst() like so:

  printFirst(infinite(), 43)

Then our program with crash with a stack overflow error, when we try to evaluate the infinite function. But if we call the function with the parameters inversely:

  printFirst(43, infinite())

Our program doesn’t crash, and just prints out the number 43. This is because the second parameter (y) doesn’t get evaluated when we call the parameter. The call by name arrow in the function definition delays the evaluation of the expression until its needed, and in this case it is not used or evaluated.

Summary

In this short post we examined the differences between call by value and call by name in our Scala functions. We saw how to specify that a parameter in a function should be call by name (with the => arrow), and looked at some examples of the two different types.

Source Code

As always, the source code for this post is available on Github.