计划中的初学者..尝试使用以下代码来测试lambda的等价性并让
(lambda (x y)
(+ x y)
10
(* x 2))
(let ((k 10)
(y (* 2 k)))
(+ k y))
输出
#<procedure>
. . k: undefined;
cannot reference undefined identifier
>
任何帮助将不胜感激
答案 0 :(得分:0)
Scheme let
有两个限制。
let
定义的变量对后续定义的主体不可见。let
定义的变量对定义本身不可见。第一个限制适用于您的示例。
(let ((k 10)
(y (* 2 k)))
(+ k y))
在此示例中,k
和y
在同一let
中定义。 y
的正文确实知道k
。为了使k
的正文y
可见,您必须使用两个let
表达式。
(let ((k 10))
(let ((y (* 2 k)))
(+ k y)))
为了避免这种嵌套,Scheme提供了let*
替代方案。
(let* ((k 10)
(y (* 2 k)))
(+ k y))
如果您阅读let*
的规范,则还应考虑阅读letrec
的规范,这将消除第二个限制。
答案 1 :(得分:0)
FWIW,相当于lambda
构造
(let ((k 10))
(let ((y (* 2 k)))
(+ k y)))
是
((lambda (k)
((lambda (y)
(+ k y))
(* 2 k)))
10)
答案 2 :(得分:0)
let
形式的正文之前不能使用let
中的绑定。因此,您需要定义k
:
(define k 99)
(let ((k 10)
(y (* 2 k))) ; the k here is not the one in the same `let`
(+ k y))
; ==> 208
let
只是被称为匿名过程的语法糖。它等于这个:
((lambda (k y)
(+ k y))
10
(* 2 k))
使用此语法可能更明显k
不能分配给10
?还有另一种称为let*
的语法,它允许您使用以前的绑定:
(let* ((k 10)
(y (* 2 k))) ; the k here is not the one in the same `let`
(+ k y))
; ==> 30
它等于嵌套的匿名过程调用:
((lambda (k)
((lambda (y)
(+ k y))
(* 2 k)))
10)
此处很容易看到k
中的(* 2 k)
是绑定到10
的{。}}。