Scalera tips : var immutable vs. val mutable

Let’s suppose we want to define a class that has state (a list, e.g.).
If we followed the pure functional paradigm, each time we changed our instance’s state, this should return a new modified instance (with the new state).

class Foo(val state: List[Int]) {

  def mutate(n: Int): Foo =
    new Foo(state :+ n)

}

val initialFoo = new Foo(List())
assert(initialFoo.state==List())

val mutatedFoo = initialFoo.mutate(1)
assert(initialFoo.state==List())
assert(mutatedFoo.state==List(1))

…if you just think about it, it’s a case class copy method behavior.

But let’s handle the situation where we have to integrate with some legacy application and we cannot manage changes over our Foo generating a new instance.

In this case, the state is determined by the internal list, and not the Foo instance itself.

A first approach could be using a val with a mutable list(which is thread-safe):

import scala.collection.mutable
class Foo {

  private val _state: mutable.ListBuffer[Int] = 
    ListBuffer()

  def mutate(n: Int): Unit = 
    _state += n

  def state: mutable.ListBuffer[Int] =
    _state

}

austinpowers

And, on the other hand, we could use a var with an immutable list (it’s not thread-safe):

class Foo {

  private var _state: List[Int] = 
    List()

  def mutate(n: Int): Unit = 
    synchronized(_state :+= n)

  def state: List[Int] = 
    synchronized(_state)

}

Note that we’ve had to use a synchronize for protecting the state facing concurrent accesses.

Which is the best option?

Even it’s true that the second option generates more boilerplate, using the first one we could have the following situation:

val foo = new Foo
assert(foo.state==mutable.ListBuffer())
val retrievedState = foo.state += 2
assert(foo.state==ListBuffer()) //ERROR!

When returning the mutable internal list, we’ve broken the referential transparency principle and we’ve lost the access control over the state.

It’s probably dependent on the use case, but in general, the functional approach aims to generate new modified copies so potential side effects are avoided.

Anuncios

2 thoughts on “Scalera tips : var immutable vs. val mutable

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s