On Apr 30, 2009, at 9:43 AM, Julien wrote:
-here's the clojure code:
(def text1 "testing thread") (def T (proxy [Thread] [] (run [] (println "T thread : (eval (println text1))") (eval (println text1))(println "T thread : (eval (read-string \"(println text1)\"))")(eval (read-string "(println text1)")) ))) (println "Main thread : (eval (println text1))") (eval (println text1)) (println "Main thread : (eval (read-string \"(println text1)\"))") (eval (read-string "(println text1)")) (. T start)
At any given time, within any given thread, the "current namespace" is bound to the var *ns*, a dynamic variable. Every thread has (potentially) an independent value for *ns*. If no call to "bind" has been made since the thread started, *ns* within that thread will be bound to its root binding which is the clojure.core namespace:
user=> (.getRoot (var *ns*)) #<Namespace clojure.core> Within the body of T:- In the first eval, the expression (println text1) was compiled in the main thread while the user namespace was current. text1 was resolved at compile time to become user/text1.
The entire expression was resolved like this: user=> `(eval (println text1)) (clojure.core/eval (clojure.core/println user/text1)) and the compiled.When T ran, the current namespace was clojure.core, but the reference to text1 was fully qualified and referenced the intended var in user. Note that in this case "(clojure.core/println user/text1)" ran to completion while it was being evaluated as an argument to eval. What eval actually received was "nil". eval of nil produced nil.
- In the second eval, read-string produced a data structure that was passed to eval. eval tried to do its work by compiling the expression and running it. That compilation occurred within thread T where the current namespace was clojure.core. Since clojure.core/text1 doesn't exist, text1 could not be resolved and the compiler threw an exception.
You can "fix" the second eval either by changing \"(println text1)\" to \"(println user/text1)\" or by surrounding the body of T with a "binding" call that binds *ns* to user, or binds it to any namespace and then sets it with a call to "(in-ns 'user)".
--Steve
smime.p7s
Description: S/MIME cryptographic signature