Perhaps I've been a little bit rude with if-let, but I really do not see how

(if-let [{erros :email} (function-returning-errors email password)]
        true
        false)

is not misleading. I now that the tested value is the one returning from the 
function call and not the value assigned to errors local, but exactly this is 
misleading in reading the code.  

What I'm saying is that in such a case (i.e. if-let + sequence destructoring) 
you're just coding wrong. I'm not say that if-let is wrong. So I prefer not to 
use if-let when I'm restructuring because I could easily create a subtle bug.

I don't like complexity when is not needed. You already have the if-let 
limitation in the number of locals you can use. Now you have this subtle 
behaviour to pay attention to.  If I now that something is dangerous I prefer 
to stay a little bit apart from it.

Mimmo

On Jan 30, 2013, at 8:51 PM, Gary Verhaegen <gary.verhae...@gmail.com> wrote:

> 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
> 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