I know I can do the following in Common Lisp:
CL-USER> (let ((my-list nil))
       (dotimes (i 5)
         (setf my-list (cons i my-list)))
       my-list)
(4 3 2 1 0)
How do I do this in Clojure? In particular, how do I do this without having a setf in Clojure?
 
                        
Clojure bans mutation of local variables for the sake of thread safety, but it is still possible to write loops even without mutation. In each run of the loop you want to
my-listto have a different value, but this can be achieved with recursion as well:Clojure also has a way to "just do the looping" without making a new function, namely
loop. It looks like alet, but you can also jump to beginning of its body, update the bindings, and run the body again withrecur."Updating" parameters with a recursive tail call can look very similar to mutating a variable but there is one important difference: when you type
my-listin your Clojure code, its meaning will always always the value ofmy-list. If a nested function closes overmy-listand the loop continues to the next iteration, the nested function will always see the value thatmy-listhad when the nested function was created. A local variable can always be replaced with its value, and the variable you have after making a recursive call is in a sense a different variable.(The Clojure compiler performs an optimization so that no extra space is needed for this "new variable": When a variable needs to be remembered its value is copied and when
recuris called the old variable is reused.)