On Jan 28, 3:26 pm, Raoul Duke <rao...@gmail.com> wrote: > [gmail is freaking out, apologies if this is sent twice] > > On Thu, Jan 28, 2010 at 12:23 PM, DanL <leidis...@gmail.com> wrote: > > When exactly would a lazy sequence evaluate to false? > > i thought it was happening with code like: > > (let [final-answer (and (map #(= "foo" %) ["foo" "bar"]))] > (if final-answer "yay" "humbug")) > > in a larger routine. it wasn't doing what i expected from my tests, > and when i put in a println then it suddenly worked. which led me to > figure it was something about laziness. changing the if to read > > (if (vec final-answer) ...) > > fixed it. > > ?
Raoul, I think if you evaluate this code piece-by-piece the behavior will become more clear. From your example I feel like you are trying to determine if all elements in a given collection/sequence are of the value "foo?" Start from the inside and work your way out. user> (map #(= "foo" %) ["foo" "bar"]) (true false) So here we returned a lazy seq of boolean values based on the anonymous function being used as a predicate. user> (and (map #(= "foo" %) ["foo" "bar"])) (true false) Now we pass the result to and, but yet the same result is returned. >From what I can tell you expected and to make sure all values in this sequence were true, but lets look at the doc string. 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 Notice that and is a macro and that it doesn't expect a sequence as argument, but rather 0 to multiple expressions (also note that the doc string appears to have a typo or some sort). So the seq you passed and is treated as one expression, and that expression is treated as true, and it is the last expression so it is returned. To summarize, the and function simply returned the same exact sequence that it was passed in the first place. The reason "yay" is returned is because a seq will evaluate to true. user> (if '(true false) "yay" "humbug") "yay" user> (if '() "yay" "humbug") "yay" user> (if '(nil) "yay" "humbug") "yay" user> (if nil "yay" "humbug") "humbug" I'm not sure how calling vec on final-answer "fixed" your problem unless there is some code you are not showing. user> (if (vec '(true false)) "yay" "humbug") "yay" user> (if (vec '()) "yay" "humbug") "yay" user> (if (vec nil) "yay" "humbug") "yay" However, the following will work. user> (every? (partial = "foo") ["foo" "bar"]) false I think the problem was more of a misunderstanding with the and function and not lazy sequences. -- 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