Reputation: 69
I am currently learning Clojure and I am unsure of how to use the STM to do concurrency. The task I am trying to accomplish is very simple, I have a vector of strings, I want to run a function on each of the strings concurrently, and replace the string with what the function returns.
I can currently do this very easily with pmap:
(pmap function string_vector)
How can I do this same thing using the STM in Clojure?
Upvotes: 0
Views: 132
Reputation: 91617
The STM in clojure is about maintaining the state of mutable things over time. These things that have a state that changes from moment to moment are said to have "an identity". Just as you have an identity that is "you" for your whole life, even if "you" at three months old may not recognise "you" at 120 years old. So lets put something mutable in your example so we have an excuse to use the STM:
Let's make a publicly available mutable place to store the strings and then change them there in parallel:
user> (def current-strings (ref ["a" "b" "c"]))
#'user/current-strings
user> (dosync (alter current-strings (fn [the-string-at-this-instant]
(pmap #(.toUpperCase %) the-string-at-this-instant))))
("A" "B" "C")
user> @current-strings
("A" "B" "C")
user>
In this example we created a transaction that changed the state of our collection of strings by applying a function to it. Internally that function happened to compute the new values in parallel.
to make this more interesting let's make a vector of mutable things, and then in a parallel update a bunch of independently mutable things each in it's own transaction:
user> (def current-strings [(ref "a") (ref "b") (ref "c")])
#'user/current-strings
user> (doall
(pmap (fn [ref-to-update]
(dosync (alter ref-to-update #(.toUpperCase %))))
current-strings))
("A" "B" "C")
user> (map deref current-strings)
("A" "B" "C")
user>
As you can see, none of this needs the STM, because all these operations can be handled with the other mutable types in clojure, atoms would be a great choice. And playing with refs is fun too! Have fun!
Upvotes: 1
Reputation: 3801
STM is a way of sharing data across threads. If you don't need to coordinate at all (which you don't in this example), there's no real reason to use STM.
Upvotes: 2