4

I don't understand the meaning of this sentence (from Scala-Threading/Odersky/18-stateful-objects.txt line 88):

a class might be stateful without defining or inheriting any vars because it forwards method calls to other objects that have mutable state.

Can anyone give me a good example of this kind of situation in Scala ?

Peter Neyens
  • 9,770
  • 27
  • 33
liango
  • 786
  • 7
  • 18

2 Answers2

7
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
liango
  • 786
  • 7
  • 18
Gabriele Petronella
  • 106,943
  • 21
  • 217
  • 235
3
class FileWrapper(file : java.io.RandomAccessFile) {

  def isEmpty = file.read() < 0

  def next = file.read()
}

In the above example file maintains its own state but FileWrapper only forwards method calls to the file object.

Ramón J Romero y Vigil
  • 17,373
  • 7
  • 77
  • 125