Reputation: 98
Trying out this snippet of code and doesn't seem to be working quite right..
(defn- multiple_of?
[div num]
(= (mod num div) 0))
(defn sum_of_multiples_from
([start] (sum_of_multiples_from start 0))
([start total]
(if (<= start 0)
total
(recur (dec start) (or (multiple_of? 3 start) (multiple_of? 5 start)
(+ total start) start)))))
I receive the following error:
java.lang.Boolean cannot be cast to java.lang.Number
I am guessing it has to do with:
(recur (dec start) (or (multiple_of? 3 start) (multiple_of? 5 start)
(+ total start)
start)))))
But I'm not sure why, I'm new to clojure, so I'm trying to get a grasp of recur.
Upvotes: 1
Views: 98
Reputation: 13069
You really want a conditional expression for your recur
, and one that always returns a number. For example:
(defn sum_of_multiples_from
([start] (sum_of_multiples_from start 0))
([start total]
(if (<= start 0)
total
(recur (dec start)
(if (or (multiple_of? 3 start) (multiple_of? 5 start))
(+ total start)
total)))))
Note that this is a weird way to implement this in a functional language. You're really picking values from a range and adding them up, so it's better to implement this as a filter and a reduce, for example:
(reduce + (filter #(or (multiple_of? 3 %) (multiple_of? 5 %)) (range 50)))
=> 543
Upvotes: 4
Reputation: 8910
Your or
call returns a boolean ((multiple_of? 3 start)
) as soon as start is a multiple of 3.
In Clojure, or
always returns one of its arguments -- either the first truish one if one exists, or the last falsish one otherwise.
Upvotes: 3