Reputation: 4201
I am trying to some code that simple prints out everything in a list.
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
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 recur
s 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