"If one needs thread-local storage, you use a Java ThreadLocal directly."
No, you just use a dynamic Var for that or with-local-vars. Normally, in Clojure, values are bound to symbols. This means that a symbol is mapped to a value. In general, you can not change this mapping once it is set. This is true in local contexts, such as when using (let) or with function arguments. In cases where you need to change the mapping, you'll need to have an extra layer of indirection, since you can not actually change it. To do this, Clojure gives you a few constructs such as Vars, Refs, Agents and Atoms. A Var is a mapping from thread to value, with support for an optional root value (like a default value if no value for the current thread exists on the Var). So instead of doing Symbol -> Value, you will do Symbol -> Var(CurrentThread) -> Value. By default, Vars just have a root, and you can not dynamically add new thread to value mappings to them unless they are declared dynamic. Now, when you do "def" or what is called "intern", you are creating a new mapping from Symbol to Var on the current Namespace. This can be thought of as the global context. When you use a symbol, Clojure will first look for it inside local contexts, and if it does not find it there, it will look for it in the current namespace. If it is a fully qualified symbol, it'll go looking for it directly inside the namespace you qualified. What this means is that, on a Namespace, you can not map Symbols to Values, you can only map Symbols to Vars. In local contexts, you can map symbols to whatever you want, but not in the global context. The reason Clojure always forces you to map symbols to vars at the namespace level are unknown to me, but that's what it does. All that to say, if you want a per-thread value, go ahead and use a dynamic Var. You can choose to make it global, by using def, or to make it local, by creating a local Var using (with-local-vars). No need to use Java's ThreadLocals directly. Keep in mind that if you have sub-threads, they won't always inherit their parent's bindings. They only do inside (future) and if using (bound-fn). On Wednesday, 8 February 2017 14:39:59 UTC-8, Ernesto Garcia wrote: > > Hi Alex, thanks for your thorough response. > > It seems to me that Clojure vars are just not intended to be used as > thread-locals in general. They happen to use thread-local storage in order > to implement dynamic scoping, which is the original intent. > > That is why vars are either global (interned in a namespace), or confined > to a dynamic scope (via with-local-vars). > > If one needs thread-local storage, you use a Java ThreadLocal directly. > -- 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 --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.