1

我正在努力区分 let、letrec、let* ......因为方案不是我的主要编程语言,我的记忆已经不存在很长时间了..我有这个功能..现在我对 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 '()))))

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

-> [Q1] 它尾递归吗?

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

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

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

4

3 回答 3

7

与 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)
)

回顾一下:

  1. 用 letrec 声明的变量的范围是 ALL 在 letrec 的主体内。编译器做了一些魔术,所以在声明结束后引用被替换。
  2. 用 let* 声明的变量的作用域都是变量声明后 let* 作用域内的表达式。
  3. 而用 let 声明的变量的作用域只是 let 的主体,而不是声明部分。
于 2014-05-25T05:39:42.723 回答
1

如果我没记错的话,这个结构需要,letrec而不是letorlet*因为 bodyfunc:rec_func指的是它自己。如果您在此处使用letlet*,则嵌套 lambda 中的符号func:rec_func将绑定到顶级表单之外可见的任何定义,或者如果没有此类定义,则为 undefined - 这也不是您想要的。

于 2014-05-25T02:00:35.207 回答
0

[Q1]它尾递归吗?

回答是的,它进行尾递归。

[Q2]那么,尾递归应该始终使用 letrec 吗?

回答有两种方法可以解释您的问题。

  1. 我们应该总是使用letrec尾递归吗?我不认为你打算问这个。但 ...

    答案是不。顶级 lambda 函数也可用于尾递归。

  2. 应该letrec总是使用尾递归吗?

    答案是:任何递归函数最好是尾递归的。如果可以的话,你应该让它尾递归。

[Q3]那么 line6 是什么?

第 6 行的代码执行递归调用。

假设start0end5res1。在第一次调用中func:rec_funcx是空列表()i5,并且y是空列表()

在第 6 行调用第一个递归函数时,参数是(cons i x)(- i res)(cons (func i) y),其计算结果为:(5)4((func 5)

在下一次迭代中,参数是(4 5)3((func 4) (func 5))

它一直持续到i小于start。然后递归停止结果((0 1 2 3 4 5) ((func 0) (func 1) (func 2) (func 3) (func 4) (func 5)))

第 7 行的代码在满足递归的终止条件时执行,即 when(>= i start)为 false。

于 2014-05-25T03:38:47.867 回答