Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clojure loop receiving IllegalArgumentException Key must be integer clojure.lang.APersistentVector.invoke

Tags:

clojure

I'm stuck trying to get a simple loop in Clojure to work and I don't know how to proceed to get rid of the exception. I'm trying to write an arrange function to exchange items in a vector. Here is the code.

(defn exchange [v i] 
  (let [[src dst] i]
    (assoc v dst (v src) src (v dst))))

(defn arrange []
  (loop [idxs [0 0] 
         deck [\a \b \c \d \e] 
         pts [[0 1] [2 3] [4 1]]]
    (println idxs deck pts)
    (empty? pts)
      deck
      (recur (first pts) (exchange deck idxs) (rest pts))))    

;(arrange)
;[b e d c a]

If I remove the println, I don't see anything in the REPL. I came from COBOL so you know I'm struggling to pick this up:) Any suggestions to make this more idiomatic would be appreciated.

6/11- This is the corrected code. arrange should have only two paramaters in the loop.

(defn arrange []
  (loop [deck [\a \b \c \d \e] 
         lst [[0 1] [2 3] [4 1]]]
    (if (empty? lst)
      deck
      (recur (exchange deck (first lst)) (rest lst)))))

or even better, use (reduce exchange deck lst) instead as per @Magos!

like image 570
shirha Avatar asked Sep 22 '26 22:09

shirha


1 Answers

You are missing an if, and you need to end the loop on idxs, not pts (or you will miss the final index pair):

(if (empty? idxs)
  deck
  (recur (first pts) (exchange deck idxs) (rest pts)))

should work better.

like image 79
bsvingen Avatar answered Sep 25 '26 19:09

bsvingen