David J.
David J.

Reputation: 1913

Why do these filters, one using AND and one using OR, evaluate the same in Clojure?

Here is a filter using AND in Clojure:

(filter #(and (= 0 (mod % 3) (mod % 5))) (range 100))

It returns, as I would expect,

(0 15 30 45 60 75 90)

On the other hand, here is the same filter using OR instead of AND:

(filter #(or (= 0 (mod % 3) (mod % 5))) (range 100))

To me, it doesn't make sense that it would return the exact same list, but it does. Why doesn't the list with OR return

(3, 5, 6, 9, 10 ...)

?

Upvotes: 3

Views: 56

Answers (1)

Chad Taylor
Chad Taylor

Reputation: 756

When you use =, it looks to see if all the parameters passed to it are equal. In each example filter checks if 0 = (mod % 3) = (mod % 5). Instead, check each case individually:

(filter #(or (= 0 (mod % 3)) (= 0 (mod % 5))) (range 100))

You might also consider using zero?. I think it makes it a little easier to read and helps in avoiding issues like this one.

(filter #(or (zero? (mod % 3)) (zero? (mod % 5))) (range 100))

Upvotes: 4

Related Questions