Meikel Brandmeyer <m...@kotka.de> writes: > So using alter is the absolutely correct and nothing bad will > happen. However you might construct superfluous default nodes in case > the action is retried. They are not assoc'd to the map, though.
Understood. Thanks for the explanation. > The anonymous function is not necessary. I missed this note in the documentation, despite having run my eyes over it several times: ,---- | Sets the in-transaction-value of ref to: | | (apply fun in-transaction-value-of-ref args) `---- > What leads you to the idea it would be different? Only the lack of confirming documentation walking through the behavior under conflict. > I think this is the whole point about STM, that you don't have to > worry about such things. Yes, but then writing with concurrency in mind is all about imagining the odd things that will almost never happen, but you need to design in anticipation of. The STM presents some "magic" that's supposed to alleviate the programmer of some worry, but without being clear about the scope of that "magic" and the problems it alleviates, I don't know which problems to ignore. > There is (get the-map id (default-node)), but this does not assoc the > value to the map. I assume your (default-node) is a little more > complicated - and in particular non-constant. Yes, you assume correctly. I thought through whether I could work with the get-with-default operation, but concluded that I need the semantics of the Java functions I had written as examples. > I think the let above solves this problem, no? Yes, I think it does. I'll either return a value that some prior thread inserted in the map or the value that I just inserted. I take it that `dosync' doesn't return any value until all of its changes can be committed without conflict, such that the returned value with follow from a successful commit against what was a consistent view of the refs involved. > In contrast to alter, commute would in case of conflict just go on and > assoc the id again. When you say "assoc the id again", do you mean that in the example time line above, B's alteration of the map would succeed, even though A's alteration had succeeded just prior, without B retrying? If so, there's more to be explained about `commute'. I'm imagining the commit-time rules saying that if competing changes to the refs touched by `commute' can be ignored, because the changes can be applied in either order. But if the operation was something like `inc', two competing threads would both commit a value one greater than when both transactions started, which would result in a final value only one greater, rather than two, as intended. Reading the documentation again, I think these characterizations are wrong. It sounds like `commute' runs /again/ at the commit point of the transaction, but the whole transaction doesn't have to run again. It's not clear whether `commute' /always/ invokes the provided function twice, or only in the case of having detected a conflict against the target ref at the would-be commit point. > I think alter is exactly the right tool. Good. I can understand `alter'. I'd still like to understand more about `commute'. I appreciate the discussion. -- Steven E. Harris -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en