因此,我花了很多时间阅读并重新阅读The Little Schemer中第9章的结尾,其中应用Y组合器是为该length功能开发的.我认为我的困惑归结为一个单独的声明,对比两个版本的长度(在组合器被分解之前):
A:
((lambda (mk-length)
(mk-length mk-length))
(lambda (mk-length)
(lambda (l)
(cond
((null? l) 0 )
(else (add1
((mk-length mk-length)
(cdr l))))))))
B:
((lambda (mk-length)
(mk-length mk-length))
(lambda (mk-length)
((lambda (length)
(lambda (l)
(cond
((null? l) 0)
(else (add1 (length (cdr l)))))))
(mk-length mk-length))))
Run Code Online (Sandbox Code Playgroud)
第170页(第4版)指出A.
当我们将它应用于参数时返回一个函数
而B
不返回功能
从而产生自我应用的无限回归.我很难过.如果B受到这个问题的困扰,我不知道A如何避免它.
所以,据我了解,以下内容:let,let*,letrec并letrec*在方案/球拍使用人工合成的糖.
现在,如果我有一个简单的程序:
(let ((x 1)
(y 2))
(+ x y))
Run Code Online (Sandbox Code Playgroud)
它被翻译成:
((lambda (x y) (+ x y)) 1 2)
Run Code Online (Sandbox Code Playgroud)
如果我有:
(let* ((x 1)
(y 2))
(+ x y))
Run Code Online (Sandbox Code Playgroud)
它被翻译成:
((lambda (x) ((lambda (y) (+ x y))) 2) 1)
Run Code Online (Sandbox Code Playgroud)
现在,对于我的第一个问题,我理解一个letrec表达式的含义,它允许一个人在let中使用递归,但我不明白它是如何完成的.什么是letrec翻译成?
例如,会是什么
(letrec ((x 1)
(y 2))
(+ x y))
Run Code Online (Sandbox Code Playgroud)
被翻译成?
第二个问题是类似的letrec*- 但letrec*我不明白它究竟有何不同letrec?而且,letrec*表达式将被翻译成什么?