I find it helpful to view if-let as a minor variation on if, with the only difference being that you choose to bind the results of the test-expression to some name(s). if-let doesn't care about the values bound to the variables named in binding-target (which might be an arbitrarily complex destructuring). If that's not what you want, then if-let isn't the right tool for the job.
(if test-expression expression-evaluated-when-test-expression-is-truthy expression-evaluated-otherwise) is similar to (if-let [ binding-target test-expression ] expression-evaluated-when-test-expression-is-truthy expression-evaluated-otherwise) expands to roughly this, except that test-expression is evaluated only once: (if test-expression (let [binding-target test-expression] expression-evaluated-when-test-expression-is-truthy) expression-evaluated-otherwise) It took me a little while to understand that this is how it worked when I began with clojure, but it seems pretty natural now. if-let is really simple-minded. don't over-think it. // ben On Wed, Jan 30, 2013 at 10:42 AM, Mimmo Cosenza <mimmo.cose...@gmail.com>wrote: > that means never use if-let with sequential destructoring, which brings me > to say: never use if-let, because I don't' like to remember such thing > while coding and then become crazy to catch my error because of a > misleading language feature. > > mimmo > > > On Jan 30, 2013, at 10:32 AM, James Xu <xumingming64398...@gmail.com> > wrote: > > > Agree with you that it is very misleading when using map-destructure in > > if-let, the same applies to sequential-destructure: > > > > user=> (if-let [[_ x] [1 nil]] true false) > > true > > > > > > > > On 13-1-30 下午5:23, "Mimmo Cosenza" <mimmo.cose...@gmail.com> wrote: > > > >> Uhm, I do not agree. > >> > >> Suppose tha you have a function returning a map of errors (a valip > >> validator lib real case) like the following > >> > >> {:email ["Email can't be empty"] :password ["Password can't be empty"]} > >> > >> If I want to select just the email errors I would write something like > >> that > >> > >> (if-let [{errors :email} (function-returning-error email password)] > >> true > >> false) > >> > >> Reading the above code you're led to believe that if there are email > >> errors, errors local binding will be true. Instead, it returns true even > >> if the are no email errors but there are password errors and you never > >> get the false branch. > >> > >> An if you want to catch password errors you would write something like > >> > >> (if-let [{errors :password} (function-returning-errors email password)] > >> true > >> false) > >> > >> In either case you never get the false branch when > >> function-returning-errors return an error which is not the one you're > >> looking for > >> > >> Mimmo > >> > >> > >> On Jan 30, 2013, at 10:05 AM, James Xu <xumingming64398...@gmail.com> > >> wrote: > >> > >>> From the expansion we can see that if-let determine the result based on > >>> the second param, in your case: {:key2 "a string"}, not the local > >>> binding > >>> you assumed(key1), and > >>> I think it is reasonable, for example, if we have the following code: > >>> > >>> (if-let [{key1 key2} {:key2 "a string"}] > >>> true > >>> false)) > >>> > >>> > >>> Should if-let determine the result based on key1? key2? IMO {key1 key2} > >>> in > >>> a whole is more reaonable. And {key1 key2} == {:key2 "a string"}, then > >>> the > >>> result is true. > >>> > >>> > >>> > >>> On 13-1-30 下午4:51, "Mimmo Cosenza" <mimmo.cose...@gmail.com> wrote: > >>> > >>>> Hi all, > >>>> I'm a little bit confused about the semantic of if-let macro. > >>>> > >>>> Suppose to call it as follows with map destructoring: > >>>> > >>>> (if-let [{key1 :key1} {:key2 "a string"}] > >>>> true > >>>> false)) > >>>> > >>>> It returns true. > >>>> > >>>> But, > >>>> > >>>> (let [{key1 :key1} {:key2 "a string"}] > >>>> (if key1 > >>>> true > >>>> false)) > >>>> > >>>> returns false. > >>>> > >>>> > >>>> The macro expansion of the former explains why > >>>> > >>>> (macroexpand-1 '(if-let [{key1 :key1} {:key2 "a string"}] true false)) > >>>> > >>>> returns > >>>> (clojure.core/let [temp__3971__auto__ {:key2 "a string"}] (if > >>>> temp__3971__auto__ (clojure.core/let [{key1 :key1} temp__3971__auto__] > >>>> true) false)) > >>>> > >>>> the consequence, IMHO, is that I would never suggest to use map > >>>> restructuring inside and if-let binding, because the syntax let me > >>>> think > >>>> the result its the opposite of its semantic, > >>>> > >>>> Am I completely wrong? > >>>> > >>>> mimmo > >>>> > >>>> > >>>> -- > >>>> -- > >>>> 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/groups/opt_out. > >>>> > >>>> > >>> > >>> > >>> -- > >>> -- > >>> 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/groups/opt_out. > >>> > >>> > >> > >> -- > >> -- > >> 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/groups/opt_out. > >> > >> > > > > > > -- > > -- > > 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/groups/opt_out. > > > > > > -- > -- > 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/groups/opt_out. > > > -- -- 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/groups/opt_out.