难以理解 Scheme 中 let 和 lambda 的用法
Difficulty in understanding let and lambda usage in Scheme
我很难理解以下代码的范围:
(define (create-counter (x 1))
(let ([count 0])
(lambda()
(let ([temp count])
(set! count (+ x count)) temp))))
如果我使用:
(let ((c (create-counter ))) (+ (c) (c) (c) (c)))
代码工作但是如果我尝试:
(+ (create-counter)(create-counter)(create-counter)(create-counter))
这不起作用,给我一个 0。有人可以帮助我彻底理解这个吗?如果可能的话,请与 C/C++ 等其他语言进行比较,这样我会更容易掌握这一点。谢谢
当您调用 "create-counter" 时,它会创建一个计数器,然后 return 是一个引用该特定计数器的过程。当您调用 "create-counter" 四次时,您将创建四个独立的计数器;每个程序都引用它自己的计数器。当您调用 "create-counter" 一次然后调用结果过程四次时,它只创建一个计数器,并将其递增四次。
很难将它与 C 进行比较,因为 C 和 C++ 在闭包方面非常薄弱; return 在另一个函数内部定义的函数并不容易。
最接近的类比可能是 C++ 中的 "counter" 对象;将 "create-counter" 视为包含单个整数的对象的构造函数,并将生成的过程视为 "increment" 递增该对象中包含的计数器的方法。那么,在您的第二个示例中,您创建了四个不同的对象,而在您的第一个示例中,您创建了一个对象并调用了它的 "increment" 方法四次。
(define (create-counter (x 1))
(let ([count 0])
(lambda()
(let ([temp count])
(set! count (+ x count)) temp))))
转换为:
auto create_counter(int x=1){
int count=0;
return [x,count]()mutable{
int r=count;
count+=x;
return r;
};
}
返回闭包对象的简单 C++14 函数。
当你这样做时:
(let ((c (create-counter ))) (+ (c) (c) (c) (c)))
是:
auto c = create_counter();
auto r = c()+c()+c()+c();
return r;
它创建一个计数器,然后 运行s 它 4 次,返回 0 1 2 3 并加到 6。
在这种情况下:
(+ ((create-counter))((create-counter))((create-counter))((create-counter)))
是:
auto r = create_counter()()+create_counter()()+create_counter()()+create_counter()();
return r;
它创建了 4 个计数器,并且 运行 每个计数器一次。第一次你 运行 一个计数器你得到 0。所以这加到 0。
闭包对象有状态。每次调用它时 returns 一个更大的数字。
现在你可能对C++11/14 lamnda不熟悉
auto create_counter(int x=1){
int count=0;
return [x,count]()mutable{
int r=count;
count+=x;
return r;
};
}
是
struct counter {
int x,count;
int operator()(){
int r=count;
count+=x;
return r;
};
};
counter create_counter(int x=1){
return {x,0};
}
加上一些语法糖。
我修复了您的原始代码中似乎存在语法错误的问题。我不是专家,所以可能我理解错了。
顺便说一句,简要的创建计数器如下所示:
auto create_counter(int x=1){
return [=,count=0]()mutable{
int r=count;
count+=x;
return r;
};
}
我很难理解以下代码的范围:
(define (create-counter (x 1))
(let ([count 0])
(lambda()
(let ([temp count])
(set! count (+ x count)) temp))))
如果我使用:
(let ((c (create-counter ))) (+ (c) (c) (c) (c)))
代码工作但是如果我尝试:
(+ (create-counter)(create-counter)(create-counter)(create-counter))
这不起作用,给我一个 0。有人可以帮助我彻底理解这个吗?如果可能的话,请与 C/C++ 等其他语言进行比较,这样我会更容易掌握这一点。谢谢
当您调用 "create-counter" 时,它会创建一个计数器,然后 return 是一个引用该特定计数器的过程。当您调用 "create-counter" 四次时,您将创建四个独立的计数器;每个程序都引用它自己的计数器。当您调用 "create-counter" 一次然后调用结果过程四次时,它只创建一个计数器,并将其递增四次。
很难将它与 C 进行比较,因为 C 和 C++ 在闭包方面非常薄弱; return 在另一个函数内部定义的函数并不容易。
最接近的类比可能是 C++ 中的 "counter" 对象;将 "create-counter" 视为包含单个整数的对象的构造函数,并将生成的过程视为 "increment" 递增该对象中包含的计数器的方法。那么,在您的第二个示例中,您创建了四个不同的对象,而在您的第一个示例中,您创建了一个对象并调用了它的 "increment" 方法四次。
(define (create-counter (x 1))
(let ([count 0])
(lambda()
(let ([temp count])
(set! count (+ x count)) temp))))
转换为:
auto create_counter(int x=1){
int count=0;
return [x,count]()mutable{
int r=count;
count+=x;
return r;
};
}
返回闭包对象的简单 C++14 函数。
当你这样做时:
(let ((c (create-counter ))) (+ (c) (c) (c) (c)))
是:
auto c = create_counter();
auto r = c()+c()+c()+c();
return r;
它创建一个计数器,然后 运行s 它 4 次,返回 0 1 2 3 并加到 6。
在这种情况下:
(+ ((create-counter))((create-counter))((create-counter))((create-counter)))
是:
auto r = create_counter()()+create_counter()()+create_counter()()+create_counter()();
return r;
它创建了 4 个计数器,并且 运行 每个计数器一次。第一次你 运行 一个计数器你得到 0。所以这加到 0。
闭包对象有状态。每次调用它时 returns 一个更大的数字。
现在你可能对C++11/14 lamnda不熟悉
auto create_counter(int x=1){
int count=0;
return [x,count]()mutable{
int r=count;
count+=x;
return r;
};
}
是
struct counter {
int x,count;
int operator()(){
int r=count;
count+=x;
return r;
};
};
counter create_counter(int x=1){
return {x,0};
}
加上一些语法糖。
我修复了您的原始代码中似乎存在语法错误的问题。我不是专家,所以可能我理解错了。
顺便说一句,简要的创建计数器如下所示:
auto create_counter(int x=1){
return [=,count=0]()mutable{
int r=count;
count+=x;
return r;
};
}