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 
> <javascript:>> 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 
>> <javascript:>
>> 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 <javascript:>
>> 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 <javascript:>.
>> 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