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

Reply via email to