2

I am trying to write a custom max function in Clojure, which should support one or more arguments. However, I am running into an error that I cannot figure out. Here is the below function:

(defn my-max [arg & rest]                                                            
  (loop [m arg c rest]                                                               
    (cond (empty? c) m                                                               
          (> m (first c)) (recur m (rest c))                                         
          :else (recur (first c) (rest c)))))

And I encounter the following error when attempting to evaluate the function:

user> (my-max 2 3 1 4 5)                                                                                                                                                    
ClassCastException clojure.lang.ArraySeq cannot be cast to clojure.lang.IFn  user/my-max (NO_SOURCE_FILE:5)

I thought this would work because I was under the assumption that rest was just a sequence. I was able to get this function to work without a variadic signature, where the argument is simply a sequence:

(defn my-max [coll]                                                                                                                                                            
  (loop [m (first coll) c (rest coll)]                                                                                                                                         
    (cond (empty? c) m                                                                                                                                                         
          (> m (first c)) (recur m (rest c))                                                                                                                                   
          :else (recur (first c) (rest c)))))

1 Answer 1

4

The problem appears to be a name collision. You have used the name rest for the tail sequence of your calling arguments. Then you subsequently try to use the function rest, but that sequence is seen instead.

Sign up to request clarification or add additional context in comments.

4 Comments

Yes, that was it. I am not sure why I didn't see that earlier -- sometimes I need a sanity check.
This is where perhaps one day we might hope for some compiler warnings.
@A. Webb - agree, this is exactly why we need some more static type checking in Clojure. Would pick up this kind of thing immediately.
For this particular case, checking wouldn't need types. Lists do not implement IFn so attempting to invoke a 'rest' argument would be undoubtedly a programming mistake.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.