I have a question in Clojure about recur. If I have a let-statement inside the loop, can the recur call be applying to the let statement instead of the values of the loop? For example, in this scenario:
(defn someFunction [listA listB]
("do something here...."
[new-listA new-listB]))
(defn anotherFunction [listA listB]
("do something here...."
[new-listA new-listB]))
(defn myFunction [firstList secondList]
(loop [list1 (someMutation firstList)
list2 (someMutation secondList)]
(if (= "true" (someCondition))
(let [[newlist1 newlist2]
(someFunction list1 list2)]
(recur newlist1 newlist2))
(anotherFunction list1 list2) )))
is (recur newlist1 newlist2) applying to the loop or to the let? And is there a way of skipping this let statement and calling recur directly with the two values returned by "someFunction", assuming that I can't change the fact that "someFunction" returns a vector with two arguments?
recur
always recurs to the closest loop
or function, whichever is closer to the recur
form. It does this by compiling to essentially a loop/jump statement that changes the values of the loop variables and then jumps back to the loop/fn point. This way it only uses one stack frame and can run full speed. This design has some intentional trade-offs:
This last one requires that you keep the let expression or something equivalent such as a destructuring form. Loops do allow destructuring of the arguments just like functions:
(loop [[a b] [1 2]]
(println a b)
(if (< a 10)
(recur [(inc a) (inc b)])))
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
9 10
10 11
So you could write your loop expression to take the result of someFunction
directly
(loop [[list1 list2] [(someMutation firstList) (someMutation secondList)]]
...
(recur (someFunction ...))