Is there a reason why 'some' returns "nil" instead o "false"?

1,058 views
Skip to first unread message

Jacobo Polavieja

unread,
Jun 14, 2012, 11:31:36 AM6/14/12
to clo...@googlegroups.com
Hi!

I've just started learning Clojure today. I've started reading "Clojure - Functional Programming for the JVM" (http://java.ociweb.com/mark/clojure/article.html).

Anyway, on the collections part (http://java.ociweb.com/mark/clojure/article.html#Collections) it called my attention that 'some' returns "nil" instead of "false". The examples given (being stooges a vector of Strings) are:

(not-every? #(instance? String %) stooges) ; -> false
(some #(instance? Number %) stooges) ; -> nil

Is there a reason why (some) doesn't return false also? I've read through the doc but as I supposed, there's no explanation about the reasoning behind it.

Thanks!

David Nolen

unread,
Jun 14, 2012, 11:46:53 AM6/14/12
to clo...@googlegroups.com
not-every? is a predicate (note the ?)

some is not.

--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@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+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Tassilo Horn

unread,
Jun 14, 2012, 12:02:30 PM6/14/12
to clo...@googlegroups.com
Jacobo Polavieja <jacobop...@gmail.com> writes:

Hi Jacobo,

> (not-every? #(instance? String %) stooges) ; -> false
> (some #(instance? Number %) stooges) ; -> nil
>
> Is there a reason why (some) doesn't return false also?

`some` is no predicate (else it would have a ? appended). It simply
returns the first truthy (i.e., not false nor nil) value of applying the
given fn to the elements of the fiven seq one after the other.

user> (some seq [[] (list) (hash-map) [1 2 3] [4 5]])
(1 2 3)

That said, if you use `some` with a proper predicate as you did, then
its safe to use it as a predicate, too. The fact that it returns nil
instead of false is an implementation detail, but nil is as falsy as
false, so who cares...

Bye,
Tassilo

Jacobo Polavieja

unread,
Jun 14, 2012, 12:15:15 PM6/14/12
to clo...@googlegroups.com
Thank you both! I had the epiphany now and realized it is what you both stated. But you had already answered! So quick :).

I think I've tried too run too much and have read through too fast. All morning setting up Clojure and learning Clojure. It's fun but my brain may now need some rest...

Thanks!

Jim - FooBar();

unread,
Jun 14, 2012, 1:14:30 PM6/14/12
to clo...@googlegroups.com
you can always make your own with a little macro but if you just started learning today you may want to stick with some...

I, like you, wanted a version that returns true or false a couple of months ago.. here it is:

(defmacro in?
 "Returns true if colle contains elm, false otherwise."
 [colle elm] 
`(if (some #{~elm} ~colle) true false))

Hope that helps...notice this is a macro not a function - the call to in? will expand at compile time into the body of the macro...in other words you've just created some new syntax!

Jim

David Nolen

unread,
Jun 14, 2012, 1:16:16 PM6/14/12
to clo...@googlegroups.com
Definitely something that should not written as a macro :)

David

Jim - FooBar();

unread,
Jun 14, 2012, 1:19:09 PM6/14/12
to clo...@googlegroups.com
I don't see why not if you really really need to return true/false...
Of course as Tassilo said nil is falsey so it is unlikely that you would ever need to do that...

Jim

nicola...@gmail.com

unread,
Jun 14, 2012, 1:20:11 PM6/14/12
to clo...@googlegroups.com

>> (defmacro in?
>>  "Returns true if colle contains elm, false otherwise."
>>  [colle elm] 
>> `(if (some #{~elm} ~colle) true false))

Yes. Should not be a macro. (There is no reason for it to be a macro).
On top of that, it is not very often useful to convert nil to false as 
clojure understands nil/not-nil as false/true everywhere.
(Someone corrects me if there is a counter example.)

Might be useful for java interop?
Then I would define a 
(defn to-bool [x]
   (if x true false))
and use it when necessary.

nicola...@gmail.com

unread,
Jun 14, 2012, 1:22:00 PM6/14/12
to clo...@googlegroups.com
On Thu, Jun 14, 2012 at 6:19 PM, Jim - FooBar(); <jimpi...@gmail.com> wrote:
I don't see why not if you really really need to return true/false...

Because it can be written as a function. Macro are only for things that cannot be easily written as functions.
(And then it should be backed by functions that are usable but less convenient.)
(That is the general theory. There might be exceptional situation where macro are better. )

Jim - FooBar();

unread,
Jun 14, 2012, 1:23:06 PM6/14/12
to clo...@googlegroups.com
On 14/06/12 18:20, nicola...@gmail.com wrote:
> (defn to-bool [x]
> (if x true false))
> and use it when necessary.

why add the extra overhead of potentially boxing/unboxing x in such a
simple case? Its not like the macro is getting out of control...Its a
one liner...

Jim

nicola...@gmail.com

unread,
Jun 14, 2012, 1:26:01 PM6/14/12
to clo...@googlegroups.com

why add the extra overhead of potentially boxing/unboxing x in such a simple case? Its not like the macro is getting out of control...Its a one liner...

Because functions are first class and not macros. 
Ex:

(map to-bool l)

 

Jim - FooBar();

unread,
Jun 14, 2012, 1:37:08 PM6/14/12
to clo...@googlegroups.com
I  have a functionize macro if I ever want to do that with a macro but I think we are getting off topic here...
all I'm saying is that if I want to keep a loop very tight and want to perform a couple of checks inline, why clutter the body of the loop  with 'if's or 'some's or whatever...you want to keep it readable but inlined at the same time...functions deal with Object don't they? I do agree on all the points made here and I am indeed very careful with my macros...

Jim

Tassilo Horn

unread,
Jun 14, 2012, 2:32:11 PM6/14/12
to clo...@googlegroups.com
"Jim - FooBar();" <jimpi...@gmail.com> writes:

> (defmacro in?
> "Returns true if colle contains elm, false otherwise."
> [colle elm]
> `(if (some #{~elm} ~colle) true false))

Except for the complains that this doesn't need to be a macro (which I
agree with), it is also wrong.

user> (in? [nil false] nil)
false
user> (in? [nil false] false)
false

Bye,
Tassilo

Jim - FooBar();

unread,
Jun 14, 2012, 2:46:43 PM6/14/12
to clo...@googlegroups.com
nice catch and point taken...

however the exact same thing would happen if this was a function...it's
just wrong !

Jim

Stuart Halloway

unread,
Jun 14, 2012, 2:47:42 PM6/14/12
to clo...@googlegroups.com
(doc boolean)

Cheers,
Stu

Stuart Halloway
Clojure/core
http://clojure.com

Tassilo Horn

unread,
Jun 15, 2012, 2:27:08 AM6/15/12
to clo...@googlegroups.com
"Jim - FooBar();" <jimpi...@gmail.com> writes:

> nice catch and point taken...
>
> however the exact same thing would happen if this was a
> function...it's just wrong !

Yes. A correct version is

(defn in? [coll e]
(some (partial = e) coll))

Bye,
Tassilo

Jim - FooBar();

unread,
Jun 15, 2012, 5:47:14 AM6/15/12
to clo...@googlegroups.com
If just wrapping 'some' I think this is easier to read

(defn in? [coll e]
(some #{e} coll))

thanks for your time :-)

Jim

Jim - FooBar();

unread,
Jun 15, 2012, 5:49:30 AM6/15/12
to clo...@googlegroups.com
aaaa sorry...you meant to return boolean not the actual element!

my bad...

Jim

Tassilo Horn

unread,
Jun 15, 2012, 8:40:36 AM6/15/12
to clo...@googlegroups.com
"Jim - FooBar();" <jimpi...@gmail.com> writes:


>>> Yes. A correct version is
>>>
>>> (defn in? [coll e]
>>> (some (partial = e) coll))
>>
>> If just wrapping 'some' I think this is easier to read
>>
>> (defn in? [coll e]
>> (some #{e} coll))
>>
>> thanks for your time :-)
>
> aaaa sorry...you meant to return boolean not the actual element!

No, my variant also returns nil for "e is not in coll", but the
difference is that my version works for nil and false values:

(in? [nil false] nil) => true
(in? [nil false] false) => true

whereas your version with the hash-set returns nil and false in those
cases.

Bye,
Tassilo
Reply all
Reply to author
Forward
0 new messages