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.


Reply via email to