I’d start by the distinction that exists in Scala between def, val and var.
def – defines an immutable label for the right side content which is lazily evaluated – evaluate by name.
val – defines an immutable label for the right side content which is eagerly/immediately evaluated – evaluated by value.
var – defines a mutable variable, initially set to the evaluated right side content.
scala> def something = 2 + 3 * 4 something: Int scala> something // now it's evaluated, lazily upon usage res30: Int = 14
scala> val somethingelse = 2 + 3 * 5 // it's evaluated, eagerly upon definition somethingelse: Int = 17
scala> var aVariable = 2 * 3 aVariable: Int = 6 scala> aVariable = 5 aVariable: Int = 5
According to above, labels from def and val cannot be reassigned, and in case of any attempt an error like the below one will be raised:
scala> something = 5 * 6 <console>:8: error: value something_= is not a member of object $iw something = 5 * 6 ^
When the class is defined like:
scala> class Person(val name: String, var age: Int) defined class Person
and then instantiated with:
scala> def personA = new Person("Tim", 25) personA: Person
an immutable label is created for that specific instance of Person (i.e. ‘personA’). Whenever the mutable field ‘age’ needs to be modified, such attempt fails:
scala> personA.age = 44 personA.age: Int = 25
as expected, ‘age’ is part of a non-mutable label. The correct way to work on this consists in using a mutable variable, like in the following example:
scala> var personB = new Person("Matt", 36) personB: Person = Person@59cd11fe scala> personB.age = 44 personB.age: Int = 44 // value re-assigned, as expected
as clear, from the mutable variable reference (i.e. ‘personB’) it is possible to modify the class mutable field ‘age’.
I would still stress the fact that everything comes from the above stated difference, that has to be clear in mind of any Scala programmer.