On Tue, Dec 16, 2008 at 1:22 PM, falcon <shahb...@gmail.com> wrote: > > I am fairly familiar with basic functional programming. I've studied > a bit of scheme and Haskell. I don't quite understand Vars, Refs, > Agents and Atoms. I am a Java developer and have worked with > concurrency constructs: locks, synchronized, Executor framework, etc.
Vars are like global variables in other languages. The "root binding" is an initial default value that is shared by all threads. When you alter a var, those changes will not be seen by other threads. Since changes aren't seen by other threads, there are no coordination issues. The "binding" construct acts as if the var has been altered by set!, but it is automatically restored to its previous value upon exiting the scope of the binding construct. The semantics can seem quite odd if you're not used to this kind of construct, and most languages don't have anything quite like this (I think I've only seen it in Lisp and Scheme), so Vars can take a while to get the hang of. Refs are like ref cells in ML, boxes in Scheme, or pointers in other languages. It's a "box", that you can change the contents of. But unlike the other languages, the twist is that you can only make the change inside of a transaction. Agents are somewhat like Erlang actors, but you can always read the contents of agents without needing to send a message, and as a result, they aren't really useful for the kind of distributed programming that Erlang is designed for. Also since Java threads aren't as lightweight as Erlang threads, I'm not totally convinced agents are as useful as the corresponding constructs in Erlang. But in any case, this is the way to accomplish asynchronous things in Clojure. Atoms are the newest construct, designed primarily to speed up memoization caching versus the former ref implementation. It's reportedly a bit faster than refs, but less safe, in the sense that you've got to make sure your program won't fail if the atom swap is executed multiple times from a transaction retrying. The only real guarantee an atom provides is that the "swap" command is atomic, in the sense that Clojure automatically checks that nothing altered the value between when you read it and when you swap it with a new value. But it's probably not much use for things other than memoization and very similar scenarios. My take on all this: when in doubt, use Refs, as they are most likely what you want. --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---