难以理解let和lambda在Scheme中的使用

时间:2016-03-20 16:56:53

标签: c++ lambda scheme let

我很难理解以下代码的范围:

 (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 ++,我会更容易抓住这个。感谢

2 个答案:

答案 0 :(得分:2)

当您调用“create-counter”时,它会创建一个计数器,然后返回一个引用该特定计数器的过程。当您四次调用“创建计数器”时,您将创建四个独立的计数器;每个程序都指自己的计数器。当您调用“create-counter”一次然后调用生成的过程四次时,它只创建一个计数器,并将其递增四次。

将它与C进行比较有点困难,因为C和C ++在闭包方面相当薄弱;返回在另一个函数中定义的函数并不容易。

最接近的模拟可能是C ++中的“计数器”对象;将“create-counter”视为包含单个整数的对象的构造函数,并将结果过程视为“增量”方法,该方法增加该对象中包含的计数器。在第二个示例中,您将创建四个不同的对象,在第一个示例中,您将创建一个对象并将其“增量”方法调用四次。

答案 1 :(得分:2)

(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;

创建一个计数器,然后运行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。

闭包对象具有状态。每次调用它时都会返回一个更大的数字。

现在你可能不熟悉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;
  };
}