Reputation: 59202
Let's say I create a variable, x
, in a Clojure namespace, store the associated var in another variable (y
), and then unmap x
:
(ns user)
(def x 0)
(def y (var x))
(ns-unmap 'user 'x)
If I evaluate y
in the REPL, it prints #'user/x
, even though the symbol user/x
is not associated with this variable anymore.
user=> y
#'user/x
user=> (deref y)
0
user=> (deref #'user/x)
Syntax error compiling var at (REPL:0:0).
Unable to resolve var: user/x in this context
Things get really confusing if I create a new variable associated with the symbol x
:
(def x 1)
(def z (var x))
Now, the repl prints both y
and z
as #'user/x
, even though those variables point to different var objects:
user=> y
#'user/x
user=> (deref y)
0
user=> z
#'user/x
user=> (deref z)
1
user=> (= z y)
false
Why does the REPL print #'user/x
when evaluating y
here?
Upvotes: 1
Views: 61
Reputation: 91887
To think properly about this, you need to understand how vars and namespaces work in Clojure.
n
has a definition named s
, then it maps the symbol n/s
to a var that is named by n/s
.So, you defined x
, yielding a var (call it v
) labeled user/x
and containing 0, and stored in the namespace user
. Then you removed that mapping from the user
namespace. But the var v
still exists, and still knows it's called user/x
. So you can still look at it by traversing through y
, which has of course saved the actual var object, and no longer cares what namespace was used to look up the var. You can, e.g. print its name and dereference it to see the value 0 that was locked in there.
You later define a new var named x
in the user
namespace, yielding a new var that knows it's referred to by user/x
. But it's a distinct var, so they can hold different values, and the user
namespace now points to a different var than the one you stored in y
.
Upvotes: 0