11

One of the major advantages of software transactional memory that always gets mentioned is composability and modularity. Different fragments can be combined to produce larger components. In lock-based programs, this is often not the case.

I am looking for a simple example illustrating this with actual code. I'd prefer an example in Clojure, but Haskell is fine too. Bonus points if the example also exhibits some lock-based code which can't be composed easily.

durron597
  • 7,590
  • 9
  • 37
  • 67
dbyrne
  • 1,378
  • 1
  • 11
  • 15
  • 1
    Interesting, but sounds more like a StackOverflow question to me. – Steve Apr 06 '11 at 20:50
  • This question has been asked there 4 minutes later. http://stackoverflow.com/questions/5518546/software-transactional-memory-composability-example Would someone migrate and merge this question (if possible)? – Job Apr 06 '11 at 20:54
  • Yeah after I posted it here, I realized it would probably be better on Stackoverflow. If someone can merge it, thats fine with me. – dbyrne Apr 06 '11 at 21:18

1 Answers1

9

Suppose you have some bank accounts:

(def accounts 
 [(ref 0) 
  (ref 10) 
  (ref 20) 
  (ref 30)])

And a atomic "transfer" function:

(defn transfer [src-account dest-account amount]
  (dosync
    (alter dest-account + amount)
    (alter src-account - amount)))

Which works as follows:

(transfer (accounts 1) (accounts 0) 5)

(map deref accounts)
=> (5 5 20 30)

You can then easily compose the transfer function to create a higher level transaction, for example transferring from multiple accounts:

(defn transfer-from-all [src-accounts dest-account amount]
  (dosync
    (doseq [src src-accounts] 
      (transfer src dest-account amount))))

(transfer-from-all 
  [(accounts 0) (accounts 1) (accounts 2)] 
  (accounts 3) 
  5)

(map deref accounts)
=> (0 0 15 45)

Note that all of the multiple transfers happened in a single, combined transaction, i.e. it was possible to "compose" the smaller transactions.

To do this with locks would get complicated very quickly: assuming the accounts needed to be individually locked then you'd need to do something like establishing a protocol on lock acquisition order in order to avoid deadlocks. It's very easy to make a hard-to-detect mistake. STM saves you from all this pain.

mikera
  • 20,617
  • 5
  • 75
  • 80