Question

From there

Trying to introduce memoization into the recursion algorithm.

case class Memo[A,B](f: A => B) extends (A => B) {
  private val cache = mutable.Map.empty[A, B]
  def apply(x: A) = cache getOrElseUpdate (x, f(x))
}

private val fib: Memo[Int, BigInt] = Memo {
  case 0 => 0
  case 1 => 1
  case n => fib(n-1) + fib(n-2) 
}

def foo(n: Int) = {
  fib(n)
} 

Does it mean that if we use mutable state and functional value (defined by val.. well almost functional value) then it is not thread-safe?

(val fib - looks like global scoped mutable variable/object)

Was it helpful?

Solution

I'd say yes, there can be a problem if more threads are calling foo at the same time. Even though I was thinking that if you're only adding to the map and always the same value for a key, there is no guarantee that it must work. If implementation of getOrElseUpdate method of Map is for whatever reason stateful, it would not work. The contract of mutable Map is by definition not thread-safe.

If you can, add synchronization to your map and you're fine:

private val cache = new HashMap[A, B] with SynchronizedMap[A, B]
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top