5

I just finished Martin Odersky's scala class at Coursera. Scala being my first FP language, I was excited by the idea of limiting mutable state. This allows for much easier concurrency and also makes the code super maintainable.

While learning all this, I realized you could guarantee the mutability of an object as long as it had no mutable variables and only referenced immutable objects. So now I can do everything by creating a new state instead of modifying an old one, use tail recursion when possible.

Great. So I can only do this so far up the chain. At some point, my application needs to be able to modify some existing state. I know where put in concurrency control at this point, locks, blah blah. I'm still defaulting to my standard multi-threaded concurrency control I've always used.

Oh scala community, is there a better way? Monads maybe?

EDIT: this question is a bit general, so I wanted to give a use case: I have a machine learning algorithm that stores several collections of data. They have functions that return updated representations of the data (training, etc), all immutable. Ultimately I can keep this return-updated-state pattern going up the chain to the actual object running the simulation. This has a state that is mutable and holds references to the collections. I may want to distributed to multi-cores, or multi-system.

Colin Godsey
  • 1,293
  • 9
  • 14
  • 4
    Hide mutability inside actors – om-nom-nom Dec 10 '12 at 15:35
  • ive used akka actors in a project before, it did the job very well and worked good for distributing load across servers. is there a lighter weight version of actors for the local scale? – Colin Godsey Dec 10 '12 at 15:39
  • 1
    I think this question is too subjective. Maybe better for programmers.stackexchange – frankc Dec 10 '12 at 15:42
  • @ColinGodsey There's Scala Actors (as opposed to Akka Actors) as well, the implementation that comes with the standard Scala distribution. They are expected to be replaced by Akka actors in the future, but have you tried them? – Faiz Dec 11 '12 at 05:03
  • 2
    @ColinGodsey: I'm also using Scala for machine learning and I had a [related concern](http://stackoverflow.com/questions/13260162/scala-collecting-updates-changes-of-immutable-state) regarding the performance of immutable updates. We all know the beauty of immutability but in my opinion, machine learning is a perfect example where mutable data structures are sometimes much for straightforward to use and/or faster, so choose carefully. – bluenote10 Dec 11 '12 at 08:39
  • @bluenote10 This describes my situation exactly, and confirms some of my suspicions- that it's just best to use mutable state wisely. – Colin Godsey Dec 14 '12 at 19:34

3 Answers3

4

This is a bit of a subjective question, so I won't attempt to answer the 'which is best' part of it. If your chief concern is state in the context of multithreaded concurrency, then one option may be Software Transactional Memory.

There is an Implementation (see the quickstart) of STM as provided by Akka. Depending on your use-case, it might be heavy-weight or overkill, but then again, it might be preferable to a mess of locks. Unlike locks, STM tends to be optimistic, in the same way as database transactions are. As with database transactions, you make changes to shared state explicitly in a transactional context, and the changes you describe will be committed atomically or re-attempted if a conflict is detected. Basically you have to wrap all your state in Refs which can be manipulated only in an 'atomic' block - implemented as a method that takes a closure within which you use manipulate your Refs and ScalaSTM ensures that the whole set of operations on your state either succeed or fail - there will be no half-way or inconsistent changes.

This leverages Scala's implicit parameters - all operation to Refs require a transaction object as an argument, and this is received by the closure given to atomic and can be declared implicit, so all the code within atomic will can be written in a very natural yet safe style.

The catch is, for this to be useful, you do need to use the transactional data-structures provided; so that will mean using TSet instead of Set, TMap instead of Map. These provide all-or-nothing update semantics when used in the transactional context (within an atomic block). This are very much like clojure's persistent collections. You can also build your own transactional data structures out of Refs for use within these atomic blocks.

If you are not averse to parenthesis, the clojure explanation of refs is really good: http://clojure.org/refs

Faiz
  • 16,025
  • 5
  • 48
  • 37
  • Here is the idea of STM explained, with Scala examples. http://ppl.stanford.edu/papers/scaladays2010bronson.pdf – idonnie Dec 10 '12 at 22:09
  • STM sounds really awesome, I think that's probably a model I would want to stick with. those patterns also directly apply to usage with a data grid or database, so it would be ideal for implementing a system that may be later distributed. – Colin Godsey Dec 11 '12 at 00:29
  • If you are planning on implementing a system that may later be distributed, then STM alone is may not be helpful - STM is useful as one way of coordinating access to shared state within a single process (a single JVM). Having a look at Akka as a whole maybe be a good choice. Especially the transactors. – Faiz Dec 11 '12 at 04:24
2

Depending on your use case you might be able to stick with deeply immutable object structures which you partially copy instead of actually mutating them (similar to an "updated" immutable list that shares a suffix with its original list). So-called lenses are a nice way of dealing with such structures, read about them in this SO question or in this blog post.

Sticking with immutable structures of course only works if you don't want changes to be globally observable. An example where immutable structures are most likely not an option are two concurrent clients working on a shared list, where the modifications done by client A must be observable by client B, and vice versa.

Community
  • 1
  • 1
Malte Schwerhoff
  • 12,684
  • 4
  • 41
  • 71
  • I typically try to stick with deep immutable structures, lenses sound interesting... ill have to do some more reading, im not sure if i really grasp the concept – Colin Godsey Dec 11 '12 at 00:30
0

I suggest the best way is to store the mutable variable inside a Akka actor, use message passing in and out of the Akka actor to send and receive this mutable reference. Use immutable data structures.

I have a StorageActor as follows. The variable entityMap gets updated every time something is stored via the StoreEntity. Also it doesn't need to be volatile and still works.

The Akka actor is the place where things can change, messages are passed in and out into the pure functional world.

import akka.actor.Actor
import java.util.UUID
import com.orsa.minutesheet.entity.Entity

case class EntityRef(entity: Option[Entity])

case class FindEntity(uuid: UUID)
case class StoreEntity[T >: Entity](uuid: UUID, entity: Option[T])

class StorageActor extends Actor {

  private var entityMap = Map[UUID, Entity]()

  private def findEntityByUUID(uuid:UUID): Option[Entity] = entityMap.get(uuid)

  def receive = {
    case FindEntity(uuid) => sender ! EntityRef( findEntityByUUID(uuid) )
    case StoreEntity(uuid, entity) =>
      entity match {
        case Some(store) => entityMap += uuid -> store.asInstanceOf[Entity]
        case None => entityMap -= uuid
      }
  }
}
Phil
  • 46,436
  • 33
  • 110
  • 175