It’s call by value and call by name
There have different evaluation strategies, that’s to say , “evaluate value at once” vs “evaluate value each time invoked”
for example
@counter already did a great job explaining what they are, but you may still be wondering why are they useful.
The most common use case for them is when you do not always need that value, for example the method getOrElse on the Option class is by-name. As such, you can write code like this:
def getUserById(id: Id): User =
cache
.get(key = Id) // This returns an Option[User]
.getOrElse(expensiveFetchFromDb())
This code will only call the expensive operation if it is needed.