The usual use of let can be called an anonymous procedure call:
(let ((a 10) (b 20)) (+ ab)) ;; is the same as ((lambda (ab) (+ ab)) 10 20)
The named let simply associates this procedure with a name in the scope of the procedure, so that it is equal to one letrec procedure:
(let my-chosen-name ((n 10) (acc '())) (if (zero? n) acc (my-chosen-name (- n 1) (cons n acc)))) ; ==> (1 2 3 4 5 6 7 8 9 10) ;; Is the same as: ((letrec ((my-chosen-name (lambda (n acc) (if (zero? n) acc (my-chosen-name (- n 1) (cons n acc)))))) my-chosen-name) 10 '()) ; ==> (1 2 3 4 5 6 7 8 9 10)
Note that the body of a valid value is simply assigned to a named procedure so that the name is not in the first call environment. So you can do this:
(let ((loop 10)) (let loop ((n loop)) (if (zero? n) '() (cond n (loop (- n 1))))) ; ==> (10 9 8 7 6 5 4 3 2 1)
the loop procedure is only in the body environment of let and not a shadow variable loop when let is evaluated first.
In your example, the name loop is just a name. In a circuit, each loop ultimately runs with recursion, but usually this name is used when it returns a tail and, therefore, an iterative process.
source share