"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.

Reply via email to