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.