Re: the semantic of if-let macro

2013-01-31 Thread Stuart Halloway
The docs are clear that the test occurs before the bindings:

(doc if-let)
-
clojure.core/if-let
([bindings then] [bindings then else & oldform])
Macro
  bindings => binding-form test

  If test is true, evaluates then with binding-form bound to the value of
  test, if not, yields else

Cheers,
Stu


On Thu, Jan 31, 2013 at 2:43 AM, Mimmo Cosenza wrote:

>
> On Thursday, January 31, 2013 1:49:40 AM UTC+1, Sean Corfield wrote:
>
>> but now that you've posted this, I
>> can see some potential for confusion when folks first encounter
>> if-let... Presumably the same confusion could arise for when-let?
>>
>
> yes, this is the confusion that you can incur in.
>
> 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.




Re: the semantic of if-let macro

2013-01-30 Thread Mimmo Cosenza

On Thursday, January 31, 2013 1:49:40 AM UTC+1, Sean Corfield wrote:

> but now that you've posted this, I 
> can see some potential for confusion when folks first encounter 
> if-let... Presumably the same confusion could arise for when-let? 
>

yes, this is the confusion that you can incur in.

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.




Re: the semantic of if-let macro

2013-01-30 Thread Mimmo Cosenza
On Wednesday, January 30, 2013 8:51:47 PM UTC+1, Gary Verhaegen wrote:

> For your particular use-case, what you want is more along the lines of
>
> (if-let [errors (:password (fn-returning-errors))]
> ...)
>

yes, precisely!

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.




Re: the semantic of if-let macro

2013-01-30 Thread Sean Corfield
ant 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 
>> >> 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"  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.
>
>



-- 
Sean A Corfield -- (904) 302-SEAN
An Architect's View -- http://corfield.org/
World Singles, LLC. -- http://worldsingles.com/

"Perfection is the enemy of the good."
-- Gustave Flaubert, French realist novelist (1821-1880)

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




Re: the semantic of if-let macro

2013-01-30 Thread Mimmo Cosenza
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  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  
> 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  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"  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 
> >> 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 loc

Re: the semantic of if-let macro

2013-01-30 Thread Gary Verhaegen
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 
> 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 
> 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"  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 
> >> 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"  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

Re: the semantic of if-let macro

2013-01-30 Thread Ben Smith-Mannschott
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 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 
> 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"  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 
> >> 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"  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.
> >>>>
> >

Re: the semantic of if-let macro

2013-01-30 Thread Mimmo Cosenza
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  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"  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 
>> 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"  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
>>

Re: the semantic of if-let macro

2013-01-30 Thread James Xu
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"  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 
>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"  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/grou

Re: the semantic of if-let macro

2013-01-30 Thread Mimmo Cosenza
ah, compare

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

with

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

I'm not saying that if-let is wrong, I'm saying I would never use in such a 
case (i.e. restructuring), because it led me think wrong.

mimmo

On Jan 30, 2013, at 10:23 AM, Mimmo Cosenza  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  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"  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 unsubscrib

Re: the semantic of if-let macro

2013-01-30 Thread Mimmo Cosenza
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  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"  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.




Re: the semantic of if-let macro

2013-01-30 Thread James Xu
>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"  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.




the semantic of if-let macro

2013-01-30 Thread Mimmo Cosenza
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.