class Account {
private var balance = 0
def getBalance = balance
def deposit(amount: Int): Unit = balance += amount
}
class NoVarAccount {
val account = new Account()
def balance = account.getBalance
def deposit(amount: Int) = account.deposit(amount)
}
Now, NoVarAccount
doesn't have any var
in it, but it is still stateful because it's forwarding calls to Account
which is indeed stateful.
In fact, you don't have any guarantee that calling balance
twice on the same object will get you the same result.
val account = new NoVarAccount()
account.balance // 0
account.deposit(42)
account.balance // 42
In this example, account.balance
is not referentially transparent, i.e. you cannot replace account.balance
with its return value, because it may vary.
Conversely, a stateless account would go as follows:
class StatelessAccount(val balance: Int = 0) {
def deposit(amount: Int) = new StatelessAccount(balance + amount)
}
or even more idiomatically:
case class StatelessAccount(balance: Int = 0) {
def deposit(amount: Int) = this.copy(balance = balance + amount))
}
In this case balance
is referentially transparent:
val account = StatelessAccount()
account.balance // 0
val account2 = account.deposit(42)
account2.balance // 42
account.balance // still 0