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.


Reply via email to