Search code examples
loopsif-statementclojurelisp

Stuck in a Clojure loop, need some guidance


I am stuck in a Clojure loop and need help to get out.

I first want to define a vector

(def lawl [1 2 3 4 5])

I do

(get lawl 0)

And get "1" in return. Now, I want a loop that get each number in the vector, so I do:

(loop [i 0]
   (if (< i (count lawl)) 
     (get lawl i) 
       (recur (inc i))))

In my mind this is supposed to set the value of i to nil, then if i is lower then the count of the lawl vector, it should get each lawl value and then increase the i variable with 1 and try again, getting the next value in the vector.

However, this does not work and I have spent some time trying to get it working and are totally stuck, would appreciate some help. I have also tried changing "if" to "when" with the same result, it doesn't provide any data the REPL just enters a new line and blink.

EDIT: Fixed the recur.


Solution

  • You need to consider what is "to get each lawl value" supposed to mean. Your get call does indeed "get" the appropriate value, but since you never do anything with it, it is simply discarded; Bozhidar's suggestion to add a println is a good one and will allow you to see that the loop does indeed access all the elements of lawl (just replace (get ...) with (println (get ...)), after fixing the (inc) => (inc i) thing Bozhidar mentioned also).

    That said, if you simply want to do something with each number in turn, loop / recur is not a good way to go about it at all. Here are some others:

    ;;; do some side-effecty thing to each number in turn:
    (dotimes [i (count lawl)]
      (println (str i ": " (lawl i)))) ; you don't really need the get either
    
    ;; doseq is more general than dotimes, but doesn't give you equally immediate
    ;; acess to the index
    (doseq [n lawl]
      (println n))
    
    ;;; transform the lawl vector somehow and return the result:
    ; produce a seq of the elements of lawl transformed by some function
    (map inc lawl)
    ; or if you want the result to be a vector too...
    (vec (map inc lawl))
    ; produce a seq of the even members of lawl multiplied by 3
    (for [n lawl
          :when (even? n)]
      (* n 3))
    

    This is just the beginning. For a good tour around Clojure's standard library, see the Clojure -- Functional Programming for the JVM article by Mark Volkmann.