It creates an "undefined" var if the def gets compiled but doesn't get run.
This isn't the same as an "undefined behavior" as is documented for
languages that have formal specifications (clojure of course has none). I
did qualify that def / defn inside other forms are "generally" a sign of
bad design. There are of course special cases where they might be the least
bad option.

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

> Thanks Justin,
>
> Sadly in my case those mutable container will not work because I was
> making a monkey-patch to a bug in a macro from other package.
>
> Despite what I was doing, I think "a bad design" in clojure spec is too
> weak to fit this situation. If someone tells me "it is a bad design" I
> would think I will spend more development/computation time to make it work
> but I would still expect *correct* result. "An undefined behavior" would be
> a more suitable.
>
>
> On Thursday, June 29, 2017 at 1:15:23 PM UTC-7, Justin Smith wrote:
>
>> 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 <yax...@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 clo...@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+u...@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+u...@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.
>

-- 
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