Re: How to: reduce boolean operations?

205 views
Skip to first unread message

Baishampayan Ghose

unread,
May 22, 2013, 2:09:01 AM5/22/13
to Clojure Group
Using a lambda seems to be a sane approach -

(reduce #(and %1 %2) '(false false true))
;=> false

On Wed, May 22, 2013 at 5:36 AM, Peter Mancini <pe...@cicayda.com> wrote:
> OK long time lurker here. I've been growing in my Clojure strength for a
> while now. For the most part I think I get it and I have no problem getting
> programs to do what I want. However, sometimes I get stumped.
>
> I have one function that produces a list of booleans like '(false false
> true). It seemed to me that this should be legal:
>
> (reduce and '(false false true))
>
> However that is not legal with the complaint being something about "and"
> being a macro. :-/
>
> I did get it to work with:
>
> (eval (conj '(false false true) 'and))
>
> It works but is it "correct"? Is it what you would do? I noticed that '(nil
> nil true) will cause "and" to produce false, so I am aware of that edge
> case. Anything else I should be aware of?
>
> Thanks.
>
> --
> --
> 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
> ---
> 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+u...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>



--
Baishampayan Ghose
b.ghose at gmail.com

Mark Engelberg

unread,
May 22, 2013, 2:16:36 AM5/22/13
to clo...@googlegroups.com
Using eval should be a rarity.

I'd use (every? identity [false false true]) to do a reduce-and, and I'd use (some identity [false false true]) to do a reduce-or (keeping in mind the latter actually returns nil rather than false).

Chris Ford

unread,
May 22, 2013, 3:14:13 AM5/22/13
to Clojure
The reason "and" is a macro is that it's designed to short-circuit - ie if the first result is false the rest shouldn't even be evaluated.

Using it on raw booleans works, because booleans evaluate to themselves, but it's really designed to be given forms.

The absence of a pure function for conjunction is an interesting omission, but BG's lambda fn does the trick.



On 22 May 2013 09:16, Mark Engelberg <mark.en...@gmail.com> wrote:
Using eval should be a rarity.

I'd use (every? identity [false false true]) to do a reduce-and, and I'd use (some identity [false false true]) to do a reduce-or (keeping in mind the latter actually returns nil rather than false).

atkaaz

unread,
May 22, 2013, 6:28:56 AM5/22/13
to clo...@googlegroups.com
On Wed, May 22, 2013 at 3:06 AM, Peter Mancini <pe...@cicayda.com> wrote:
 I noticed that '(nil nil true) will cause "and" to produce false, so I am aware of that edge case. Anything else I should be aware of?

What about the other edge?
user=>  (reduce #(and %1 %2) '(1 true 2))
2
user=> (eval (conj '(1 true 3) 'and))
3

user=> (doc and)
-------------------------
clojure.core/and
([] [x] [x & next])
Macro
  Evaluates exprs one at a time, from left to right. If a form
  returns logical false (nil or false), and returns that value and
  doesn't evaluate any of the other expressions, otherwise it returns
  the value of the last expr. (and) returns true.
nil
 
Thanks.

atkaaz

unread,
May 22, 2013, 6:35:29 AM5/22/13
to clo...@googlegroups.com
I find the wording of this confusing "otherwise it returns the value of the last expr. (and) returns true."
I mean, I know it returns the last true value, but that's because I've tested it not because the doc is trying(failing) to tell me so with that phrase.

John D. Hume

unread,
May 22, 2013, 7:40:34 AM5/22/13
to clo...@googlegroups.com


On May 22, 2013 5:35 AM, "atkaaz" <atk...@gmail.com> wrote:
>
> I find the wording of this confusing "otherwise it returns the value of the last expr. (and) returns true."
> I mean, I know it returns the last true value, but that's because I've tested it not because the doc is trying(failing) to tell me so with that phrase.

The next-to-last sentence describes the behavior you're talking about. The last sentence is addressing the no-args case. Starting a sentence with a parenthesized form makes it hard to read.

atkaaz

unread,
May 22, 2013, 7:48:43 AM5/22/13
to clo...@googlegroups.com
Oh i see now, thank you!

so it's like this:
"otherwise it returns the value of the last expression.
 (and) returns true."

i though "expr." is the short for of the word "expression" which requires a dot, but the dot was in fact an end of sentence.


--

Michał Marczyk

unread,
May 22, 2013, 8:38:17 AM5/22/13
to clo...@googlegroups.com
On 22 May 2013 08:09, Baishampayan Ghose <b.g...@gmail.com> wrote:
> Using a lambda seems to be a sane approach -
>
> (reduce #(and %1 %2) '(false false true))
> ;=> false

Note that this will always traverse the entire input collection,
whereas every? stops at the first false value.

Same thing goes for reducing with #(or %1 %2) vs. using some.

Cheers,
Michał

Peter Mancini

unread,
May 22, 2013, 10:54:05 AM5/22/13
to clo...@googlegroups.com
Thanks everyone for the help. The nil behavior of the 'or' version breaks what I wanted, but I may create functions that return just true or false though the odd edge case where "and" will return a value will mean I'll have to handle that. My preference would be to throw an exception but thats another cultural question about the language. What is prefered - throwing the last value or failing when not given correct input?

Ok now on to implementation. Thanks!

Jim

unread,
May 22, 2013, 10:55:38 AM5/22/13
to clo...@googlegroups.com
On 22/05/13 15:54, Peter Mancini wrote:
> The nil behavior of the 'or' version breaks what I wanted, but I may
> create functions that return just true or false though the odd edge
> case where "and" will return a value will mean I'll have to handle that.

wrap that call in a 'boolean' call (e.g. (boolean (or ...))) and you got
your true/false result :)

Jim

Peter Mancini

unread,
May 22, 2013, 11:53:05 AM5/22/13
to clo...@googlegroups.com
Well, excepts that it is not correct. It will return false when really there was a faulty collection handed to it. I'd rather catch an error like that than to pretend it didn't happen and give a result that isn't correct while also being hard to detect. If you can guarantee it won't get a bad collection then the test and exception aren't needed. Its an interesting problem - especially when you are writing "mission critical" code.

Ben Wolfson

unread,
May 22, 2013, 11:56:09 AM5/22/13
to clo...@googlegroups.com
On Wed, May 22, 2013 at 12:14 AM, Chris Ford <christop...@gmail.com> wrote:
The reason "and" is a macro is that it's designed to short-circuit - ie if the first result is false the rest shouldn't even be evaluated.

Using it on raw booleans works, because booleans evaluate to themselves, but it's really designed to be given forms.

The fact that booleans evaluate to themselves is irrelevant, and if it were relevant, "and" wouldn't work on forms in general.

--
Ben Wolfson
"Human kind has used its intelligence to vary the flavour of drinks, which may be sweet, aromatic, fermented or spirit-based. ... Family and social life also offer numerous other occasions to consume drinks for pleasure." [Larousse, "Drink" entry]

Peter Mancini

unread,
May 22, 2013, 12:17:30 PM5/22/13
to clo...@googlegroups.com
So I did some coding and came up with this but it is broken;

(= java.lang.Boolean (type false))  ;;evaluates to true

(defn all-true?
  [coll]
  (every? (cond (= java.lang.Boolean (type identity)) identity :else false) coll)) ;;compiles

(all-true? '(true true true))  ;; throws java.lang.ClassCastException: java.lang.Boolean cannot be cast to clojure.lang.IFn
(all-true? '(true true false))
(all-true? '(true true 3))

atkaaz

unread,
May 22, 2013, 12:20:03 PM5/22/13
to clo...@googlegroups.com
=> (type identity)
clojure.core$identity



--

Michael Wood

unread,
May 22, 2013, 12:29:20 PM5/22/13
to clo...@googlegroups.com
Try:

user=> (every? #(= Boolean (type %)) [true false false])
true
user=> (every? #(= Boolean (type %)) [true false false 1])
false
--
Michael Wood <esio...@gmail.com>

Peter Mancini

unread,
May 22, 2013, 12:32:26 PM5/22/13
to clo...@googlegroups.com
Duh never mind - simplified it and it works like a charm now.

(defn all-true?
  [coll]
  (every? (fn [x] (= x true)) coll))

(all-true? '(true true true))
(all-true? '(true true false))
(all-true? '(true true 3))
(all-true? '(3 \# !))

No exception on bad input data but if I really need to do that I can expand that lambda. Thanks to everyone for the help.

atkaaz

unread,
May 22, 2013, 12:34:01 PM5/22/13
to clo...@googlegroups.com
I think the exception is thrown because you basically called (every? false coll) however on my clojure version I cannot reproduce it  oh wait there we go, some bug here with empty collection (maybe someone can pick it up):
=> (every? false [1 2 3])
ClassCastException java.lang.Boolean cannot be cast to clojure.lang.IFn  clojure.core/every? (core.clj:2423)
=> (every? false [])
true

=> *clojure-version*
{:interim true, :major 1, :minor 6, :incremental 0, :qualifier "master"}





On Wed, May 22, 2013 at 7:17 PM, Peter Mancini <peter....@gmail.com> wrote:

--

atkaaz

unread,
May 22, 2013, 12:45:18 PM5/22/13
to clo...@googlegroups.com
there's another edge case when using and/or :
 getting passed an unbound var  where for example `nil?` and `str` applied to it don't throw, and of course also `or` and `and`, ie.:

=> (def a)
#'cgws.notcore/a
=> a
#<Unbound Unbound: #'cgws.notcore/a>
=> (nil? a)
false
=> (str a)
"Unbound: #'cgws.notcore/a"
=> (or a)
#<Unbound Unbound: #'cgws.notcore/a>
=> (or 1 2 a)
1
=> (or a 1 2)
#<Unbound Unbound: #'cgws.notcore/a>
=> (and 1 2 3 a)
#<Unbound Unbound: #'cgws.notcore/a>
=> (and a 1 2 3)
3

=> (type a)
clojure.lang.Var$Unbound

=> (cond a 2)
2
=> (when a 3)
3
=> (if a 4 5)
4

=> (bound? #'a)
false
=> (bound? a)   ; in case anyone was wondering
ClassCastException clojure.lang.Var$Unbound cannot be cast to clojure.lang.Var  clojure.core/bound?/fn--4837 (core.clj:4954)

=> (defn test1 [input]
     (cond (and (not (nil? input)))
       (println "received nice input=`" input "`")
       :else
       (throw (RuntimeException. (str "bad input:" input)))))
#'cgws.notcore/test1
=> (test1 1)
received nice input=` 1 `
nil
=> (test1 nil)
RuntimeException bad input:  cgws.notcore/test1 (NO_SOURCE_FILE:5)
=> (test1 a)
received nice input=` #<Unbound Unbound: #'cgws.notcore/a> `
nil

but I guess I should've put this in its proper thread aka here: https://groups.google.com/forum/#!msg/clojure/LmpcTRPUAY0/8ieaRmM7pIUJ



On Wed, May 22, 2013 at 1:28 PM, atkaaz <atk...@gmail.com> wrote:

Sean Corfield

unread,
May 22, 2013, 2:03:58 PM5/22/13
to clo...@googlegroups.com
On Wed, May 22, 2013 at 9:32 AM, Peter Mancini <peter....@gmail.com> wrote:
> (defn all-true?
> [coll]
> (every? (fn [x] (= x true)) coll))

(defn all-true?
[coll]
(every? true? coll))
--
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)

Michał Marczyk

unread,
May 22, 2013, 8:08:07 PM5/22/13
to clo...@googlegroups.com
On 22 May 2013 18:34, atkaaz <atk...@gmail.com> wrote:
> I think the exception is thrown because you basically called (every? false
> coll) however on my clojure version I cannot reproduce it oh wait there we
> go, some bug here with empty collection (maybe someone can pick it up):
> => (every? false [1 2 3])
> ClassCastException java.lang.Boolean cannot be cast to clojure.lang.IFn
> clojure.core/every? (core.clj:2423)
> => (every? false [])
> true
>
> => *clojure-version*
> {:interim true, :major 1, :minor 6, :incremental 0, :qualifier "master"}

(every? false []) should return true if and only if (false x) is
truthy for every x in [], which is certainly the case.

Cheers,
Michał

atkaaz

unread,
May 23, 2013, 12:31:06 AM5/23/13
to clo...@googlegroups.com
Well, seems to me more like this:
if [] is empty then return true
otherwise check (pred everyx in coll)
however this allows for any pred especially(in this case) invalid preds: `false` is not a function/pred
=> (false 1)
ClassCastException java.lang.Boolean cannot be cast to clojure.lang.IFn  cgws.notcore/eval2542 (NO_SOURCE_FILE:1)
=> (false true)
ClassCastException java.lang.Boolean cannot be cast to clojure.lang.IFn  cgws.notcore/eval2564 (NO_SOURCE_FILE:1)

doesn't seem truthy to me

Thanks.

Michał Marczyk

unread,
May 23, 2013, 9:48:37 AM5/23/13
to clo...@googlegroups.com
Whether (false 1) or (false true) is truthy is irrelevant. What
matters is that false returns truthy values when called with any
members of [], which is of course the case, as [] has no members. (For
it not to be the case, there would have to exist an x in [] for which
(false x) were not truthy -- clearly there is no such x.)

This is the same story as with quantification restricted to the empty set:

\forall x \in \emptyset . \phi(x)

is true regardless of what \phi is, and intimately related to how
implication works in classical logic (since the above is shorthand for
a formula involving implication):

x -> y

is true when x is false, regardless of what value y takes. (It's also
true when y is true, regardless of what value x takes; this, however,
is not relevant here.)

Cheers,
M.

atkaaz

unread,
May 23, 2013, 12:30:07 PM5/23/13
to clo...@googlegroups.com
when you say the word "false" I'm assuming you're referring to "false?" the function (not "false" the boolean value), otherwise I don't understand

so like: "What matters is that false? returns truthy values when called with any members of []"
makes sense to me.

So all I was saying above is that it should throw when [] is empty just as it does when [] is not empty, but it doesn't throw when empty because it's never called (by "it" i mean "false" not "false?")

=> (type false)
java.lang.Boolean
=> (type false?)
clojure.core$false_QMARK_
=> (fn? false)
false
=> (fn? false?)
true

But really, if you were not talking about "false?" then I don't get it (??)

John D. Hume

unread,
May 23, 2013, 1:11:48 PM5/23/13
to clo...@googlegroups.com
On Thu, May 23, 2013 at 11:30 AM, atkaaz <atk...@gmail.com> wrote:
So all I was saying above is that it should throw when [] is empty just as it does when [] is not empty, but it doesn't throw when empty because it's never called (by "it" i mean "false" not "false?")

This sort of behavior is handy for users new to the language but generally goes against the grain in a dynamic language (e.g., Clojure, Ruby, Python, JavaScript). If you want libraries to consistently error when you try to pass the wrong sort of thing to a method or function, there are a whole bunch of languages that make it inconvenient not to do that (e.g., Haskell, Scala, Java, Go). 

In a dynamic language this requires extra code in every method or function that makes assumptions about its arguments' types. People who choose dynamic languages often do so in part because of how little code it takes to do powerful things. So I think the communities largely see validation of arguments as clutter. That doesn't mean it's never done, but it's kept to a minimum. For example, clojure supports adding :pre and :post conditions to a fn's metadata, but that feature seems to be used only three times in clojure itself: twice in clojure.reflect.java and once in clojure.uuid. On the other hand, many macros in clojure.core validate their usage with the private assert-args.

This philosophical bent also comes up in question about how to design a library so that users can't mess up certain things. In the Java community, that's a common concern. In Clojure-land, the prevailing wisdom is to design and document so that it's easy to do the right thing but not worry much about people who do the wrong thing.

Gary Trakhman

unread,
May 23, 2013, 1:24:30 PM5/23/13
to clo...@googlegroups.com
A while back I saw some java slides that elude me now, they mentioned approaches to safety like defensive copying, immutability, etc..  their conclusion at the end, that I seem to remember, was it only really made sense to validate user input, a sort of wall, where anything past the wall is assumed to be valid data.  If you do idiomatic things below that layer then it will be easy to match expectations of other programmers, otherwise you'll more likely just slow the system down and go overboard than do anything useful.

Personally, I only care about these assertions when there's a real 'contract' or specification at play, at top-down-designed component boundaries.  Any validation happens at the top, and the code below is more flexible and easier to change because of it.


--

Michał Marczyk

unread,
May 23, 2013, 2:00:57 PM5/23/13
to clo...@googlegroups.com
On 23 May 2013 18:30, atkaaz <atk...@gmail.com> wrote:
> when you say the word "false" I'm assuming you're referring to "false?" the
> function (not "false" the boolean value), otherwise I don't understand

I mean false-the-Boolean-value.

To rephrase the point I was making previously, "(false x) is a truthy
value for any x in []" is a true sentence, indeed trivially so because
[] is empty. Thus (every? false []) returning true totally makes
sense.

Of course, in Haskell any such expression would be ill-typed, and that
makes sense too -- in the context of that language.

Opinions on the desired behaviour aside, in Clojure, implementing a
changed contract of every? whereby it would be required to throw when
passed something which cannot be treated as a predicate in the first
argument would be problematic -- checking that something is a function
is easy, but checking that a function has a useful unary overload is
not, in general. Well, you could simply try and call it with an
arbitrary object, but every? should be able to accept predicates which
it only makes sense to call on objects of a particular type,
predicates which have side effects, predicates which are expensive to
evaluate etc., so it's not an acceptable solution here.

And going back to opinions again, note also that in any case the
result would still be to throw an exception at runtime. The current
behaviour is also to throw at runtime, except with empty collections.
So, assuming non-empty collections are the norm, we get an exception
either way -- would having the exception come from every? rather than
the attempt to call the not-really-a-predicate object be of much help
in debugging?

Cheers,
M.

Softaddicts

unread,
May 23, 2013, 3:09:23 PM5/23/13
to clo...@googlegroups.com
At this moment after reading again this thread, I lost my sense of what false and true
mean :) I'll now stick with maybe, it's much clearer...

Luc P.
Softaddicts<lprefo...@softaddicts.ca> sent by ibisMail from my ipad!

atkaaz

unread,
May 23, 2013, 10:22:53 PM5/23/13
to clo...@googlegroups.com
Firstly let me just say that I really enjoy this conversation, ergo I thank you!


On Thu, May 23, 2013 at 9:00 PM, Michał Marczyk <michal....@gmail.com> wrote:
On 23 May 2013 18:30, atkaaz <atk...@gmail.com> wrote:
> when you say the word "false" I'm assuming you're referring to "false?" the
> function (not "false" the boolean value), otherwise I don't understand

I mean false-the-Boolean-value.

To rephrase the point I was making previously, "(false x) is a truthy
value for any x in []" is a true sentence, indeed trivially so because
[] is empty. Thus (every? false []) returning true totally makes
sense.

Alright, I see what you mean and you are right. But let's just state some assumptions(which I see as conventions):
- the system that you're using (be it logic or mathematics or whatever it is) to evaluate that that proposition is truthy  is assuming(without checking) that the components are correct (such as "false" being a pred)
- when the collection is empty -> returns true   (this is a convention imho)
  I see this system as being incomplete/incoherent/inconsistent(or insert the right word here) because of those.

"(false x) is a truthy value for any x in []"
so that is a true sentence as you say, in this system(can I call it logic? or whatever you call it really) of evaluation which you can collapse to the implementation of "every?" as it is now in clojure. You may even say that the implementation of "every?" was based on that(doesn't matter). But I say that system is "wrong" xD so to speak, "wrong" as in incomplete/inconsistent and may work somewhere else (in non-programming environments ie. on paper) where assuming that the input is valid is the norm /the only thing happening.
 In a programming environment, for me it doesn't make sense to can call or evaluate something that has (at least one) inconsistent components (inconsistent based on its own definition).
=> (every? 1 [])
true

 So it is truthy as you say, but that doesn't mean anything other than it is so(by convention/definion of) in this or that specific system(logic? or the impl. of "every?" in clojure)
 That may be acceptable to clojure community or to ppl who want to get work done, but not to (some) people who want/care for a consistent(ly defined) system. Ok, sure, I'm free to implement any constrains on top of that but if they were already implemented I couldn't get rid of them: I'll grant you that reasoning for keeping it the way it is now. But it's little things(inconsistencies I'll call them) like this which will make way for bugs which can be hard to track down. There's no guarantee that someone sometime will pass the wrong param either being aware of it or not and depending on the case it may go unnoticed and/or throw in a different place which seems quite unrelated to where the bug actually is.
  Anyway, I'm lingering, simply put: you're right   using your system of evaluation, but not when using mine; mine says: make sure everything is consistent within its own definition (so "1" above must be checked if it really fits the "pred" pattern (ie. is that a pred; is the entire proposition(or call) syntactically&semantically valid), if it doesn't the the entire call is invalid and should/will throw) and I will add to that:
 that if the collection is empty then also throw, for it doesn't make sense(to me) to check an empty collection (which you sort of assume is non empty by the name "every?") for a predicate, and therefore you are kind of forced to use a convention(aka "if empty return true") if you want to not throw in this case. (yep I would really throw on empty collection, for if you got to where you accidentally called every? on an empty collection you're way past the point in the caller where you should've checked for an empty collection anyway - that is, if you care about handling all(or most?) cases for the purpose of your program being consistent)


So, assuming non-empty collections are the norm, we get an exception
either way -- would having the exception come from every? rather than
the attempt to call the not-really-a-predicate object be of much help
in debugging?
I find it would be more consistent to throw from every? as if it makes the check that all its inputs are correct (so making sure pred is a pred ie. a fn  and not a value - that can't be used as a pred at least like a :keyword could)
And also, as I said above, I'd throw when empty collection too (but that's never gonna happen in clojure, I understand that especially because of what John D. Hume said in an above post - makes sense(if you want to get things done especially), but that is not my way(hence why I got nothing done so far - so the joke's on me :) ))

wait, shouldn't this work?
=> (:a {:a 1})
1
=> (every? :a {:a 1})
false
=> (coll? {:a 1})
true


;well at least this one works:
=> (every? {:a 1} [:a])
true
=> ({:a 1} :a)
1
;so I'm probably missing something


Cheers,
M.

Cheers & thank you for this great interaction!

Alan Thompson

unread,
May 24, 2013, 1:21:17 PM5/24/13
to clo...@googlegroups.com
Usage:  (every? pred coll)                

(see http://clojuredocs.org/clojure_core/clojure.core/every_q )

Function every? expects a predicate and a collection.  Converting the map {:a 1} into a collection returns a sequence of 2-element vectors:

user=> (seq  {:a 1})
([:a 1])

Calling the function :a on a vector returns nil, since keyword lookup only works for maps.  every? then converts the nil into fase:

user=> (every?  :a  [ nil ] )
false

Alan

atkaaz

unread,
May 24, 2013, 2:25:35 PM5/24/13
to clo...@googlegroups.com
Thank you, I see it now. Based on your comment I actually took at look at the source code for "every?" (haven't checked it before, oddly enough)

=> (source every?)
(defn every?
  "Returns true if (pred x) is logical true for every x in coll, else
  false."
  {:tag Boolean
   :added "1.0"
   :static true}
  [pred coll]
  (cond
   (nil? (seq coll)) true
   (pred (first coll)) (recur pred (next coll))
   :else false))
nil

I thought that by "coll" in the doc they meant "coll?" returns true on the input...
But now I see that first does a seq on that coll which does what you said and thus returning a vector

So these mean nothing:
=> (seq? {:a :b :c :d})
false
=> (coll? {:a :b :c :d})
true
=> (seq? [:a :b :c :d])
false
=> (coll? [:a :b :c :d])
true

=> (first [:a :b :c :d])
:a
=> (first {:a :b :c :d})
[:a :b]
=> (first {})
nil
=> (first [])
nil ;if this were me I'd probably choose to throw here
     ;or return all values in a vector to differentiate from the following:
=> (first [nil])
nil


It kinda makes sense except I wouldn't have expected that on the map it would return a vector (but then how else could it return both key and value right? )  so everyone expects the "input" to the pred would be a vector when passed in a map.

oops stumbled upon another one:
=> (get [1 2 3] 0)
1
=> (get [1 2 3] -)
nil
=> -
#<core$_ clojure.core$_@2b0dfb46>
Yep definitely better than throwing  *sarcasm*

ok check this:
=> (every? nil? nil)
true
=> (every? nil? [nil])
true
=> (every? nil? [])
true

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

=> (first nil)
nil
=> (first [nil])
nil
=> (first [])
nil


makes me think of C or something


(ok i'll stop if nobody brings it up, but really thanks to everyone that replies - and sorry for hijacking the thread)


atkaaz

unread,
May 24, 2013, 2:31:26 PM5/24/13
to clo...@googlegroups.com
typo, I meant: "thanks to everyone that replieD"

John D. Hume

unread,
May 24, 2013, 2:49:19 PM5/24/13
to clo...@googlegroups.com
On Fri, May 24, 2013 at 1:25 PM, atkaaz <atk...@gmail.com> wrote:
It kinda makes sense except I wouldn't have expected that on the map it would return a vector (but then how else could it return both key and value right? )  so everyone expects the "input" to the pred would be a vector when passed in a map.

It's actually a clojure.lang.MapEntry, which is a java.util.Map$Entry that's also a clojure.lang.IPersistentCollection that acts like a vector. So if you conj onto it, you get a vector with three things, and likewise other fns that work with colls will give you vector results, but you can also call clojure.core/key and clojure.core/val on it (or hand it to Java code that expects a map entry).

Reply all
Reply to author
Forward
0 new messages