Beautiful Code [277]
atomically (do { limitedWithdraw a1 10
; limitedWithdraw2 a2 a3 20 })
This transaction blocks until a1 contains at least 10 units, and either a2 or a3 has 20 units. However, that complicated blocking condition is not written explicitly by the programmer, and indeed if the limitedWithdraw functions are implemented in a sophisticated library, the programmer might have no idea what their blocking conditions are. STM is modular: small programs can be glued together to make larger programs without exposing their implementations.
There are many aspects of transactional memory that I have not covered in this brief overview, including important topics such as nested transactions, exceptions, progress, starvation, and invariants. You can find many of them discussed in papers about STM Haskell.[*****]
[*****] Tim Harris, Simon Marlow, Simon Peyton Jones, and Maurice Herlihy, "Composable memory transactions," ACM Symposium on Principles and Practice of Parallel Programming (PPoPP '05), June 2005; Tim Harris and Simon Peyton Jones, "Transactional memory with data invariants," First ACM SIGPLAN Workshop on Languages, Compilers, and Hardware Support for Transactional Computing (TRANSACT '06), Ottawa, June 2006, ACM; Anthony Discolo, Tim Harris, Simon Marlow, Simon Peyton Jones, and Satnam Singh, "Lock-free data structures using STMs in Haskell," Eighth International Symposium on Functional and Logic Programming (FLOPS '06), April 2006.
Transactional memory is a particularly good "fit" for Haskell. In STM, the implementation potentially must track every memory load and store, but a Haskell STM need only track TVar operations, and these form only a tiny fraction of all the memory loads and stores executed by a Haskell program. Furthermore, the treatment of actions as first-class values, and the rich type system, allow us to offer strong static guarantees without extending the language in any way. However, there is nothing to stop the adoption of transactional memory in mainstream imperative languages, although it may be less elegant and require more language support. Indeed doing so is a hot research topic; Larus and Rajwar give a comprehensive summary.[]
[] James Larus and Ravi Rajwar, Transactional Memory, Morgan & Claypool, 2006.
Using STM is like using a high-level language instead of assembly code—you can still write buggy programs, but many tricky bugs simply cannot occur, and it is much easier to focus attention on the higher-level aspects of the program. There is, alas, no silver bullet that will make concurrent programs easy to write. But STM looks like a promising step forward, and one that will help you to write beautiful code.
Beautiful Concurrency > Acknowledgments
24.6. Acknowledgments
I would like to thank those who helped me to improve the chapter with their feedback: Bo Adler, Justin Bailey, Matthew Brecknell, Paul Brown, Conal Elliot, Tony Finch, Kathleen Fisher, Greg Fitzgerald, Benjamin Franksen, Jeremy Gibbons, Tim Harris, Robert Helgesson, Dean Herington, David House, Brian Hulley, Dale Jordan, Marnix Klooster, Chris Kuklewicz, Evan Martin, Greg Meredith, Neil Mitchell, Jun Mukai, Michal Palka, Sebastian Sylvan, Johan Tibell, Aruthur van Leeuwen, Wim Vanderbauwhede, David Wakeling, Dan Wang, Peter Wasilko, Eric Willigers, Gaal Yahas, and Brian Zimmer. My special thanks go to Kirsten Chevalier, Andy Oram, and Greg Wilson for their particularly detailed reviews.
Syntactic Abstraction: