1. Overview

In this tutorial, we’ll explore the similarities and differences between methods, variables, values, and lazy values.

For more information on Scala’s core features, refer to our Intro and Guide to lazy val.

2. Methods

Methods are lazily evaluated, which means their evaluation is delayed until we call them. We can check the evaluation strategy by writing a method that prints something to the console:

object Methods extends App {
  def method: Int = {
    println("method")
    1
  }

  println("After method declaration")
  println(method)
  println(method)
}

Based on the console output, we verify that methods evaluate every time we call them:

After method declaration
method
1
method
1

Methods are also immutable, therefore we can’t change their values after we create them. When we try to do it, the compiler will fail with a “secretNumber_= is not a member of object” message:

def secretNumber: Int = 5
secretNumber = 1

3. Variables

Variables, unlike methods, evaluate eagerly. Their evaluation happens only once during the declaration:

object Variables extends App {
  var variable: Int = {
    println("variable")
    1
  }

  println("After variable declaration")
  println(variable)
  println(variable)
}

We can see that the evaluation of variables occurs only once, during declaration:

variable
After variable declaration
1
1

Unlike methods, variables are mutable as we can change their value after we create them:

var secretNumber: Int = 5
secretNumber = 1

4. Values

Values, similarly to variables, are eagerly evaluated as their evaluation occurs during declaration:

object Values extends App {
  val value: Int = {
    println("value")
    1
  }

  println("After value declaration")
  println(value)
  println(value)
}

Console output:

value
After value declaration
1
1

On the other hand, values, unlike variables are immutable. When we try to assign a new value, the compiler fails with a “reassignment to val” message:

val secretNumber: Int = 5
secretNumber = 2

5. Lazy Values

Lazy values have an exciting property. Unlike values, they are lazily evaluated, but in contrast to methods, the evaluation happens only once:

object LazyValues extends App {
  lazy val lazyValue: Int = {
    println("lazy value")
    1
  }

  println("After lazy value declaration")
  println(lazyValue)
  println(lazyValue)
}

We see that the evaluation occurs during the first usage of lazyValue:

After lazy value declaration
lazy value
1
1

On the other hand, lazy values are immutable. Similarly to values, the compiler will fail with a “reassignment to val” message when we try to assign a new value to them:

lazy val secretNumber: Int = 5
secretNumber = 1

6. Conclusion

In this short tutorial, we learned about the similarities and differences between methods, variables, values, and lazy values. We focused on their evaluation strategy and mutability.

As always, the source code with all the examples used in this tutorial is available over on GitHub.

Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.