在R7RS-小部分4.2.2绑定构造中,有一个letrec示例
(letrec ((even?
(lambda (n)
(if (zero? n)
#t
(odd? (- n 1)))))
(odd?
(lambda (n)
(if (zero? n)
#f
(even? (- n 1))))))
(even? 88))我不明白为什么letrec是必要的,因为我们已经在语言中使用了let。我试图将letrec替换为let,并在麻省理工学院11.2计划、球拍7.2 plt-r5rs、Chez计划9.5和Guile 3.0.1中得到了正确的值(#t)。letrec的真正用途是什么?
(let ((even?
(lambda (n)
(if (zero? n)
#t
(odd? (- n 1)))))
(odd?
(lambda (n)
(if (zero? n)
#f
(even? (- n 1))))))
(even? 88))发布于 2021-11-17 17:33:28
letrec不能被那样的let取代。在您的情况下,它是有效的,因为您的本地绑定正在隐藏全局绑定,然后在看起来但不是递归的调用中调用这些绑定。考虑一下
(let ((factorial
(λ (n)
(if (<= n 1)
1
(* n (factorial (- n 1)))))))
(factorial 10))如果您试图评估这一点,您将得到一个错误。但是,如果使用letrec,则不会:
(letrec ((factorial
(λ (n)
(if (<= n 1)
1
(* n (factorial (- n 1)))))))
(factorial 10))都没问题。
当然,如果您愿意通过传递函数本身作为参数来使用与U相当的东西,那么您实际上可以不使用letrec:
(let ((factorial
(λ (c n)
(if (<= n 1)
1
(* n (c c (- n 1)))))))
(factorial factorial 10))但是,您也不需要let:几乎所有的东西都只是语法上的方便。
https://stackoverflow.com/questions/69986552
复制相似问题