Fayez Abdlrazaq Deab
Fayez Abdlrazaq Deab

Reputation: 151

Clojure Function Error "Key must be integer"

I have a problem in this function although it compiles without errors!

The function gets two vectors with the same length n, another vector with length 2^n, and an index. The function does a simple calculation and then returns a vector.

The problem appears when trying to call the function. For example:

(check [1 2 3] [1 2 3] [1 2 3 4 5 6 7 8] 1)
java.lang.IllegalArgumentException: Key must be integer (NO_SOURCE_FILE:0)

Function definition:

(defn check [row1 row2 arr j]
  (
   (def x1 (nth arr (nth row1 j)))
   (def x2 (nth arr (nth row2 (- j 1))))
   (def x3 (nth arr (nth row1 (- j 1))))
   (if (<= x1 x2)
     (
      (def row1 (assoc row1 j x3))
      row1
      )
     ((def row1 (assoc row1 (- j 1) x2))
      row1)
     )
   )
  )

Upvotes: 0

Views: 2790

Answers (2)

liwp
liwp

Reputation: 6926

I cleaned up your code to this:

(defn check [row1 row2 arr j]
  (let [x1 (nth arr (nth row1 j))
        x2 (nth arr (nth row2 (- j 1)))
        x3 (nth arr (nth row1 (- j 1)))]
    (if (<= x1 x2)
        (assoc row1 j x3)
        (assoc row1 (- j 1) x2))))

I have no idea if that does what you want it to do, but the function evaluates, and returns sensible values, e.g.

user=> (check [1 2 3] [1 2 3] [1 2 3 4 5 6 7 8] 1)
[2 2 3]

Upvotes: 7

mikera
mikera

Reputation: 106351

You should probably try to fix the following problems before anything else:

  • Don't use def inside a function, you should use (let [name1 value1 name2 value2] ...) instead. def is really for defining something in a namespace, not for local values.
  • Your lets have a syntax problem, it should be (let [row1 (assoc row1 j x3)] ...) for example
  • The parenthesis on line 2 mean that you are calling the result of (def x1 (nth arr (nth row1 j))) as a function. This almost certainly isn't what you want. Turning the defs into a let should help solve this.

Upvotes: 5

Related Questions