Re: def partially done when used in if
You can see it at work in this: user=> foo (unable to resolve foo) user=> (when nil (def foo 42)) nil user=> foo (unbound var foo) When a ‘def’ form is _compiled_ -- which happens in the above case because the whole form must be compiled – then it interns the var. The ‘def’ form is parsed in DefExpr$Parser.parse() and it calls lookupVar(sym, true) – which interns the symbol if it is new (i.e., not yet seen). See various parts of: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java Sean Corfield -- (970) FOR-SEAN -- (904) 302-SEAN An Architect's View -- http://corfield.org/ "If you're not annoying somebody, you're not really alive." -- Margaret Atwood On 6/30/17, 11:28 AM, "Didier" wrote: I admit, this is very surprising. It looks like evaluation happens in two pass, like first it finds all defs and declares them, interning the symbol and creating an unbound var. And on a second pass it evaluates the full form. Can someone more informed confirm or explain in more details what's responsible for this behavior? -- 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.
Re: def partially done when used in if
I admit, this is very surprising. It looks like evaluation happens in two pass, like first it finds all defs and declares them, interning the symbol and creating an unbound var. And on a second pass it evaluates the full form. Can someone more informed confirm or explain in more details what's responsible for this behavior? -- 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.
Re: def partially done when used in if
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 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 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.
Re: def partially done when used in if
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 > 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.
Re: def partially done when used in if
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 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.
def partially done when used in if
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.