I'm learning Clojure solving the problems listed on 4clojure. One of the exercises is to create your own max
function with variable arguments.
I'm trying to solve this easy problem using the REPL and I got to this solution:
(defn my-max
[first & more] (calc-max first more))
(defn calc-max
[m x]
(cond (empty? x) m
(> (first x) m) (calc-max (first x) (rest x))
:else calc-max m (rest x)))
Which works fine but the exercise doesn't allow the use of def
and therefore I must crunch both functions into one. When I replace the calc-max
reference with its code the result is:
(defn my-max
[first & more]
((fn calc-max
[m x]
(cond (empty? x) m
(> (first x) m) (calc-max (first x) (rest x))
:else calc-max m (rest x)))
first more))
But this code doesn't work and returns the next error:
user=> (my-max 12 3 4 5 612 3)
java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn (NO_SOURCE_FILE:0)
I guess this error comes from trying to evaluate the result of the calc-max
function and I guess it's a syntax error on my part, but I can't figure out how to resolve it.
Here is the function I used to solve it. The point is not to use max at all.
(fn [& args] (reduce (fn [x y] (if (> x y) x y) ) args ) )
Real error is that you called parameter first
- it rebinds real first
function to number! Just change name to something other, and your variant will work. Although it maybe better explicitly name function, instead of calling anonymous function, for example, you can declare calc-max
as local function using letfn
, for example. So your my-max
will look like:
(defn my-max [ff & more]
(letfn [(calc-max [m x]
(cond (empty? x) m
(> (first x) m) (calc-max (first x)
(rest x))
:else (calc-max m (rest x))))]
(calc-max ff more)))
Although, I think, that you can write simpler code:
(defn my-max [& more] (reduce max more))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With