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?
(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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With