I’m trying to learn Clojure, so I figured a good way to start would be to work through the project Euler challenges with it, and the first challenge is summing all of the number below 1000 that are divisible by 3 or 5.
My original code was:
(defn div3 [input-no] (zero? (mod input-no 3)))
(defn div5 [input-no] (zero? (mod input-no 5)))
(reduce + (filter (or div3 div5) (range 1 1000)))
But that didn’t work, and it turned out that the filter would just return a list of numbers divisible by 3, and not those divisible by 5.
I changed my code to:
(defn div3or5 [input-no] (or (div3 input-no) (div5 input-no)))
(reduce + (filter div3or5 (range 1 1000)))
Which got the right result, but I don’t know why my original code didn’t work.
Could anyone shed some light on this?
If you just evaluate
(or div3 div5)in the REPL you can see what is happening:That is,
oris evaluating to the functiondiv3(whichfilteris then using, giving the behaviour you describe).The reason for this is
orwill return its first non-falsy argument (i.e. the first argument that isn’tnilorfalse); in this case, the arguments are two function objects and a function object is notnilorfalse.To put it another way, the
oris happening on the functions themselves, not the results of the functions. As Paul said, you can use an anonymous function to makeoract on the results rather than the functions themselves.