On Dec 5, 5:51 am, bOR_ <[EMAIL PROTECTED]> wrote:
> Are there any screencasts planned which will feature atoms? (I found
> that the screencasts are an excellent way of learning clojure).

Screencasts are generally a side-effect of a speaking engagement. I
imagine next time I give a talk, I'll talk about atoms too.

To address the general question about when to use atoms/refs/agents,
it helps to think of things this way:

First, note that in talking about atoms/refs/agents we are talking
about Clojure's reference types that allow changes to be seen by
multiple threads, so these three reference types are all shared
reference types.

There are two dimensions to the choice about using them, the first is
- will the changes be synchronous or asynchronous, and the second is,
will a change to this reference ever need to be coordinated with a
change to another reference or references.

Chouser made a nice diagram after I described this on IRC:

http://clojure.googlegroups.com/web/clojure-conc.png

As you can see, for coordinated changes, refs + transactions are the
only game in town, and asynchrony (beyond a set of commutes) doesn't
make much sense, so no reference type is coming to replace the X.

For independent change, you have two choices, agents and atoms.

Atoms are synchronous, the change happens on the calling thread. They
are as close to a plain variable as you get from Clojure, with a
critical benefit - they are thread safe, in particular, they are not
subject to read-modify-write race conditions. Your writes don't happen
unless they are a function of what was read. But modifications to
atoms are side effects, and thus need to be avoided in transactions.

Agents are asynchronous, and that can have important benefits. In
particular, it means actions get queued, and the sender can proceed
immediately. They provide a transparent interface to the threading
system and thread pools. Agents also cooperate with transactions in
ways that atoms cannot - e.g. agent sends are allowed in transactions
and get held until commit.

What's nice is the unified model underlying the reference types. All
can be read via deref/@, all are designed to refer to an immutable
data value, and to model change as a function of that value. All
support validators.

What that means is that, if you build your state transformation
functions as pure functions, you can freely choose/switch between the
different reference types, even using the same logic for two different
reference types.

However, they are different, and they have not been unified in the
areas in which they differ, in particular, they each have a unique
modification vocabulary - ref-set/alter/commute/send/send-off/swap!/
compare-and-set!.

In the end, Clojure is a tool, and will never be able to make
architectural decisions for you. Hopefully the above will help you
make informed choices.

The memoization example is a prime motivating case for atoms - a local
cache. It's also one that people routinely get multithread-wrong when
trying to implement with simple mutable variables.

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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to