Clojure's compiler (there's no interpreter) creates vars for every def
inside a form it compiles. Before the def actually runs it's unbound (as if
you had used declare).

Generally def and defn that are not top level forms are signs of a bad
design. If you need runtime rebinding use a proper mutable container like
and atom, ref, or agent, this is what they are for, and they eliminate a
number of gotchas that come with runtime redefinition.

On Thu, Jun 29, 2017 at 1:07 PM Kaiming Yang <yaxu...@gmail.com> wrote:

> Hi,
> Recently encountered a weird issue, A def in if clause declared a var but
> left it unbound.
>
> I encountered this issue when I was trying to implement something like
> "define a symbol if it is not defined yet". Naively I tried:
>
> (if (nil? (resolve 'foo))
>   (def foo 42))
> ; Cannot use (def foo (if (nil? (resolve 'foo)) foo 42)) because foo
> might be macro
>
> I tried in repl and the result really surprised me:
>
> user=> foo
>
> CompilerException java.lang.RuntimeException: Unable to resolve symbol:
> foo in this context,
> compiling:(/private/var/folders/1h/vhl8yb657mjf3pchm9cbc40m63f2d3/T/form-init8893781347079502941.clj:1:1062)
> user=> (if (nil? (resolve 'foo))
>   #_=>   (do (def foo 42) (prn "true-branch"))
>   #_=>   (prn "false-branch"))
> "false-branch"
> nil
> user=> foo
> #object[clojure.lang.Var$Unbound 0x6dc69f03 "Unbound: #'user/foo"]
>
> Seems once clojure interpreter declares the variable before really
> evaluate the clause with def.
>
> Is this an expected behavior? Should I ever use def in if or fn?
>
> Thanks!
> Kaiming
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to