TheRocinante
TheRocinante

Reputation: 4201

Simple Clojure example - getting an infinite loop

I am trying to some code that simple prints out everything in a list.

  1. I define numberList
  2. I create a loop - If the list is empty, print out a message and exit out. Otherwise, get the first item in the list, print it out, and recur on the list with everything but the first element.

    (def numberList [1, 2, 3, 4, 5])
    
    (loop [nums numberList]
        (when (empty? nums)
          (println "All done!"))
        (def first_item (first nums))
        (println first_item)
        (recur (rest nums))
    )
    

This code results in an infinite loop that prints "All done!" and null back to back.

Upvotes: 0

Views: 167

Answers (1)

user4813927
user4813927

Reputation:

The problem is the loop goes through all the forms you have supplied, and because the when offers you no else-form as your ending conditional-point, your loop recurs for ever, printing nil for your (first nums) (since it got empty) and "All done!".

You should use if instead of when, which gives you this form:

(if test then-form else-form)

if evaluates the test, if it returns logical true evaluates the then-form, otherwise jumps to the else-form. Also do not use def in places other than the top level, so preferably before of your loop piece and not inside of it, because it gets defined every time your loop does a loop, which is unnecessary (it also just doesn't look so nice!)

So your loop could look like this:

(def number-list [1, 2, 3, 4, 5])

(loop [nums number-list]
  (if (empty? nums)
    (println "All done!")
    (do (println (first nums)) (recur (rest nums)))))

or:

(loop [nums number-list]
  (if (seq nums)
    (do (println (first nums)) (recur (rest nums)))
    (println "All done!")))

Also if you don't have any problem with other possibilities for looping over sequences, you could for instance also use doseq or for which does a list comprehension:

(doseq [nums number-list] (println nums)) 
(for [nums number-list] (println nums))

Upvotes: 2

Related Questions