ref-set vs commute vs alter
Solution 1:
As a super simple explanation of how the Software Transactional Memory system works in clojure; it retries transactions until everyone of them gets through without having its values changed out from under it. You can help it make this decision by using ref-changing-functions that give it hints about what interactions are safe between transactions.
ref-set
is for when you don't care about the current value. Just set it to this!ref-set
saves you the angst of writing something like(alter my-ref (fun [_] 4))
just to set the value of my-ref to 4.(ref-set my-ref 4)
sure does look a lot better :).
Useref-set
to simply set the value.alter
is the most normal standard one. Use this function to alter the value. This is the meat of the STM. It uses the function you pass to change the value and retries if it cannot guarantee that the value was unchanged from the start of the transaction. This is very safe, even in some cases where you don't need it to be that safe, like incrementing a counter. You probably want to usealter
most of the time.commute
is an optimized version of alter for those times when the order of things really does not matter. it makes no difference who added which +1 to the counter. The result is the same. If the STM is deciding if your transaction is safe to commit and it only has conflicts on commute operations and none on alter operations then it can go ahead and commit the new values without having to restart anyone. This can save the occasional transaction retry though you're not going to see huge gains from this in normal code.
Usecommute
when you can.