首页 文章

letrec混乱,Scheme

提问于
浏览
-1

我正在努力解决let,letrec,let * ...之间的区别因为scheme不是我的主要编程语言,我的内存不存在很长时间..我有这个功能..现在我很困惑这里的letrec ..这又是递归 . 我可以理解......但是在这段代码中无法 Build 足够的连接..(可能仍然对递归感到困惑)有人可以解释为什么这里需要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]那么,line6是什么?我无法获得line6

3 回答

  • 1

    [Q1] 尾部递归吗?

    Answer 是的,它会进行尾递归 .

    [Q2] 那么,应该总是使用letrec进行尾递归吗?

    Answer 有两种解释问题的方法 .

    • 我们应该总是使用 letrec 进行尾递归吗?我不认为你是这么想的 . 但......

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

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

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

    [Q3] 那么line6是什么?

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

    假设 start0end5res1 . 在第一次调用 func:rec_func 时, x 是空列表 ()i5y 是空列表 () .

    当在第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行的代码在满足递归的终止标准时执行,即 (>= i start) 为false时 .

  • 0

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

    回顾一下:

    • 用letrec声明的变量的范围是在letrec体内的ALL . 编译器做了一些魔术,所以在声明结束后替换引用 .

    • 使用let *声明的变量的范围是变量声明后let *范围内的所有表达式 .

    • 用let声明的变量的范围只是let的主体,而不是声明部分 .

  • 3

    如果我没记错的话,这个构造需要 letrec 而不是 letlet* ,因为 func:rec_func 的主体指的是它自己 . 如果你在这里使用 letlet* ,嵌套lambda中的符号 func:rec_func 将被绑定到顶级表单外可见的任何定义,或者如果没有这样的定义则不定义 - 也不是你想要的 .

相关问题