If-let does the right thing. What would your intuition expect for (if-let [{a :a b :b} {:a 1 :b nil}] true false)
For your particular use-case, what you want is more along the lines of (if-let [errors (:password (fn-returning-errors))] ...) On Wednesday, January 30, 2013, Ben Smith-Mannschott wrote: > 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 > >> > > -- > -- > 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<javascript:_e({}, 'cvml', > '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 <javascript:_e({}, 'cvml', > 'clojure%2bunsubscr...@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 <javascript:_e({}, 'cvml', > 'clojure%2bunsubscr...@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.