Question

I get some weird behaviour when checking if a symbol can be resolved.

user=> ok
CompilerException java.lang.RuntimeException: Unable to resolve symbol: ok in this context, compiling:(NO_SOURCE_PATH:0)
user=> (resolve 'ok)
nil
user=> (if (resolve 'ok) "bla" (def ok 'ok))
"bla"
user=> ok
#<Unbound Unbound: #'user/ok>
user=> (def ok 'ok)
#'user/ok
user=> ok
ok

Can anyone tell me where this might come from? Is this behaviour intended?

Was it helpful?

Solution

(def ok "whatever") creates a variable named ok at compile time. The compiler scans the whole form to compile it, discovers that you will be defining a var named ok, and creates it for you (with no binding), before your form is actually executed. When the def form is actually executed, the runtime value of the expression will be assigned to the var user/ok. In your example, this never happens, because the var has already been created, and the if branch goes the other way.

Using bound? as a substitute is a terrible idea, as it tests something quite different: whether the named var (which must exist) has a binding, either permanent or thread-local.

OTHER TIPS

Since I only use it inside a macro I now use it as follows

(defmacro bla [x]
    (if (resolve x) x `(def ~x '~x)))

And now it works since def is inside the quoted form and evaluated after resolve.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top