On Jan 22, 2009, at 3:56 PM, Paul Henning wrote:

As long as no one cares if I muck with *ns*, I can make it work [...]

That brings up an important point. The var *ns* may look like a global variable in C++, but it's really a "dynamic variable"--something quite a bit safer and more powerful. "The value" of the var named *ns* is not (in the general case) a single piece of data. In the general case it's many pieces of data simultaneously. These different "values" are isolated from each other such that at any given time, each piece of running code sees only one of them. They are separated by thread--each thread has its own stack of values, and by binding depth--the effective value at any given point in the thread's runtime is the one that's associated with the nearest enclosing call to "binding". (This may be the value bound at the time "binding" was called, or it may be a value set subsequently with "set!".)

When you use "in-ns", one of its internal operations is a "set!" of *ns*. For that to succeed, *ns* must have a thread-local binding in effect at the time of the "set!". Calling "in-ns" only changes the effective namespace in the thread that calls it and only until that binding is popped off the stack by the code exiting the binding form.

The overall effect of this is that when you muck with *ns*, only your code (and code it calls) will see what you did. That isolation makes a Clojure's var much easier to reason about than a global variable would be--especially in the case of many threads accessing its "value" concurrently.

Thanks for pointing out that namespaces revert at the end of a load. Clearly matches observed behavior, but I hadn't thought about it before.

You're quite welcome.

--Steve

Attachment: smime.p7s
Description: S/MIME cryptographic signature

Reply via email to