Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ClassCastException java.lang.Long cannot be cast to clojure.lang.IFn

Tags:

clojure

I have a function that takes the number of years and salary, then recursively doubles the salary until years is exhausted. However, I keep getting this error:

ClassCastException java.lang.Long cannot be cast to clojure.lang.IFn

The Code

(defn calculate-salary
    [years salary]
    (if (= years 0)
        (salary)
        (calculate-salary (- years 1) (* salary 2))))

I'm very new to Clojure so I'm sure its something simple, but I just can't seem to figure it out.

like image 748
Jack Slingerland Avatar asked Nov 03 '14 18:11

Jack Slingerland


4 Answers

The error's meaning shouldn't be too hard to sort out: a number is being used where a function is expected.

Parenthesis in Clojure are not a grouping construct, they are used primarily to invoke function calls. If you change (salary) to salary you will return the number rather than attempting to call it as a no-argument function.

like image 55
noisesmith Avatar answered Nov 14 '22 04:11

noisesmith


Since you are new I rewrote your function to be a bit more idiomatic. Also, it uses recur so it will not consume the call stack.

(defn calculate-salary
  [years salary]
  (if (zero? years)
    salary
    (recur (dec years) (* salary 2))))

Notice the use of the zero? predicate, recur, and dec

EDIT: typos and grammar

like image 42
RedDeckWins Avatar answered Nov 14 '22 02:11

RedDeckWins


You need to remove the brackets from around salary in your if condition:

(if (= years 0)
        salary
        (calculate-salary (- years 1) (* salary 2))

the form (f arg1 arg2 ..) attempts to call f as a function with arg1, arg2 ... as arguments. Therefore (salary) attempts to invoke salary (a long) as a function with no arguments, hence the error.

like image 4
Lee Avatar answered Nov 14 '22 04:11

Lee


This

(salary)

is a function call, but salary is not a function -- it's a number.

The solution is to not wrap it in parentheses:

(if (= years 0) salary (calculate-salary (- years 1) (* salary 2)))
like image 6
mipadi Avatar answered Nov 14 '22 03:11

mipadi