Search code examples
scalastm

STM - Ref.transform


According to the documentation (as I understand it), "transform" should apply a function to an element inside a Ref-container.

In the following example: Why is the output of the second atomic expression empty, while the first actually works? I would expect the output "HELLO".

import scala.concurrent.stm._
val ref = Ref[String]("hello")            

atomic {
    implicit txn =>
    println(ref())
}                                         //> hello

atomic {
    implicit txn =>
    val uppercase = ref.transform(a => a.toUpperCase)
    println(uppercase)
}                                         //> ()

Solution

  • First of all, you shouldn't do any IO (or otherwise side-effecting) operations inside atomic block. The block might be executed multiple times, before succeeding (or failing).

    The type signature of transform is transform(f: (A) ⇒ A)(implicit txn: InTxn): Unit. It transforms the value of Ref but doesn't return new (or old) value.

    This will work:

    val value = atomic { implicit txn => 
      ref.transform(a => a.toUpperCase)
      ref.get
    }
    println(value)