Why is a repeat target not acceptable?

In clojure, this is valid:

(loop [a 5] (if (= a 0) "done" (recur (dec a)))) 

However, it is not:

 (let [a 5] (if (= a 0) "done" (recur (dec a)))) 

So, I wonder: why and let the cycle be separated, given the fact that both of them (at least conceptually) introduce lexical bindings? That is, why the cycle repeats, but let not?

EDIT: originally wrote a "loop goal" which, as I noticed, is incorrect.

+6
source share
1 answer

Consider the following example:

 (defn pascal-step [vn] (if (pos? n) (let [l (concat v [0]) r (cons 0 v)] (recur (map + lr) (dec n))) v)) 

This function calculates the n+m row of the pascal triangle from the given m row.

Now imagine let is the goal of recur . In this case, I cannot recursively call the pascal-step function from the let binding using the recur operator.

Now let's make this example a little more complicated:

 (defn pascal-line [n] (loop [v [1] in] (if (pos? i) (let [l (concat v [0]) r (cons 0 v)] (recur (map + lr) (dec i))) v))) 

Now we compute the nth row of the Pascal triangle. As you can see, I need both loop and let here.

This example is pretty simple, so you can suggest removing the let binding with (concat v [0]) and (cons 0 v) directly, but I'll just show you the concept. There may be more complex examples where let inside a loop inevitable.

+5
source

Source: https://habr.com/ru/post/955244/


All Articles