On Sat, Dec 27, 2008 at 12:03 AM, Mark Engelberg
<mark.engelb...@gmail.com> wrote:
>
> On Fri, Dec 26, 2008 at 8:35 PM, Adrian Cuthbertson
> <adrian.cuthbert...@gmail.com> wrote:
>> It's important to distinguish between updating atoms within
>> transactions and outside transactions. In the former case, one has to
>> ensure the update function can be retried without ill-effects.
>> However, outside a transaction, atoms are just mutable values, that
>> can safely be shared between threads, provided that their updating
>> does not need to be coordinated with other updates (to other atoms,
>> refs or agents).
>
> Yes, but when you write your atom-based code, you have no way to know
> whether you or others who want to reuse it will want to use it as part
> of a transaction.  atom-based code is not generally safe for
> transactions, which is why I suggested it should be avoided.  In your
> example, if incserid is used in a transaction, it is possible that
> certain serids will be skipped.  This may be acceptable, in which
> case, go ahead and use an atom, but often programs rely on subtle
> assumptions (like the serids will be issued consecutively), and your
> program can become brittle if there's a chance your code won't follow
> these assumptions.  Probably better off not to take the chance.  Stick
> with something like refs which will yield more predictable behavior,
> and thus be easier to test.  Memoization is a very special exception,
> because it really doesn't matter if something gets cached more than
> once.
>
> The whole point of Clojure seems to make as much code as possible safe
> for its software transactional memory.  Thus the persistent data
> structures, and other design details.  Although interoperating with
> Java also produces risk within transaction, generally speaking, if you
> stay within the "Clojure core", you're safe for transactions.  Except
> atoms.
>

It is certainly not the whole point of Clojure to make as much code as
possible safe for its software transactional memory. Clojure is a set
of tools. They are designed to allow for robust programs to be built,
including multithreaded programs. STM is one of those tools, but is
not a universal answer.

I think it would be wise to avoid sweeping generalizations - sweeping
generalizations are always wrong :)

There are many things that will never be safe inside transactions -
I/O in particular, and you can look at many forms of mutation (e.g.
all the Java OO mutation) as I/O of a sort. That doesn't mean that
these things aren't useful, or should be avoided. Good practice
programming with STM involves segregating the I/O portion of your code
from the transactional portion, and minimizing the footprint of your
transactions in general.

I think many people look at the facilities provided by Clojure and
hope there's also some magic recipe for good multithreaded designs.
There isn't. Even with Clojure's (or any language's) tools, you have
to think.

I don't disagree that refs should be your first choice, and that atoms
are special purpose tools for more experienced users. But they are not
just for memoization caches.

Taking the case at hand, ID generation. A modern multithreaded program
would try to avoid monotonically increasing consecutive IDs, as any
implementation of that would be a severe concurrency bottleneck. If
you were to use a ref as an ID source, every transaction would have to
line up for access to that ref. Yes, it will be predictable - with
predictably bad scalability. Using an atom for this can seriously
improve the throughput of transactions, by removing what might be the
only ref they share.

I think everyone should try to avoid dispensing advice from
theoretical arguments. You need to understand your tools, the
tradeoffs they involve, the use case at hand, and make good decisions.

Rich

--~--~---------~--~----~------------~-------~--~----~
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
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