letrec、Scheme 的混淆

use*_*570 0 scheme letrec

我正在努力区分 let、letrec、let* 之间的区别......因为scheme不是我的主要编程语言,我的记忆已经存在很长时间了..我有这个功能..现在我在这里对letrec感到非常困惑..这又是递归。我可以理解……但在这段代码中无法建立足够的连接……(可能仍然对递归感到困惑)有人可以解释为什么这里需要 letrec

(define myFunc
  (lambda (start end res func)
    (letrec ((func:rec_func
              (lambda (x i y)
                (if (>= i start)
                    (func:rec_func (cons i x) (- i res) (cons (func i) y))  ;; line6
                    (cons x (cons y '()))))))                               ;; line7
      (func:rec_func '() end '()))))
Run Code Online (Sandbox Code Playgroud)

(已编辑)我所理解的尾递归

-> [Q1] 它是尾递归吗?

-> [Q2] 那么,是否应该始终使用 letrec 进行尾递归?

此函数返回 x、y 的列表,边界为 start、end,因此它检查索引 i 是否在边界内,如果是,则执行第 6 行

-> [Q3]那么,第 6 行是什么?我无法得到 line6

est*_*arb 6

letrec、let 和 let* 的区别在于它们执行程序可用的声明。

(letrec ((X (you could use X here))
         (Y (you could use X here too))
         )
     (X also is available here)
)


(let   ((X (nope, X isn't declared yet))
         (Y (in fact, no declaration body will see X))
         )
     (But X is available here)
)


(let* ((X (X isn't available here))
         (Y (but you could use it here))
         )
     (X also is available here)
)
Run Code Online (Sandbox Code Playgroud)

回顾一下:

  1. 用 letrec 声明的变量的作用域在 letrec 的主体内。编译器做了一些魔术,所以在声明结束后引用被替换。
  2. 用 let* 声明的变量的作用域是变量声明后在 let* 作用域内的所有表达式。
  3. 用 let 声明的变量的作用域只是 let 的主体,而不是声明部分。