如何让`set!`改变`let`(Scheme)中的变量?

问题描述 投票:0回答:1

最近自学 MIT 6.5151 课程时,我按照 ps0 的要求阅读了 SICP 1 到 2.1(也按照 CS 61A Notes 的要求阅读了 2.2.1),然后阅读了 Software Design for Flexibility (SDF) Prologue, Chapter 1以及部分方案附录。

我在阅读《方案附录》时遇到了这个问题

例如,我们可以使用set!制作一个每次调用时都会增加计数的设备:

(define (make-counter)
        (let ((count 0))
            (lambda ()
              (set! count (+ count 1))
              count)))

让我们制作两个计数器:

(define c1 (make-counter))
(define c2 (make-counter))

这两个计数器具有独立的本地状态

这是一个与 this 类似的问题,但使用

(count)
而不是
count

(define (count)
  (let ((cont 0))
    (lambda ()
      (set! cont (+ cont 1))
      cont)))

然后在 MIT-Scheme 中执行以下操作:

1 ]=> ((count))

;Value: 1

1 ]=> ((count))

;Value: 1

有人可以告诉我这个版本和原来的

define count
版本有什么区别吗?是否由于上述原因,每次调用 lambda 都会创建一个
new
实例
((make-counter))
,而原始实例则不会? (最好能参考一份迄今为止尚未阅读的 SICP 章节。)

count set scheme let sicp
1个回答
0
投票

您的

count
功能

(define (count)
  (let ((cont 0))
    (lambda ()
      (set! cont (+ cont 1))
      cont)))

与您还显示的

make-counter
函数相同,只是变量名称不同。
count
是一个返回函数的函数;调用它会增加一个计数器。每个返回的函数在其词法环境中都有自己唯一的
cont
变量副本。如果你这样做

(define c1 (count))
(define c2 (count))

然后

c1
c2
有自己独立的内部计数器变量。
((count))
首先执行
(count)
,返回一个新函数,然后执行它,返回它返回的内容。然后,这个新函数会在某个时刻被垃圾收集,因为没有任何引用它可以使其保持活动状态;只能叫一次。

链接问题中的定义是

(define count
  (let ((cont 0))
    (lambda ()
      (set! cont (+ cont 1))
      cont)))

count
定义为

返回的值
(let ((cont 0))
  (lambda ()
    (set! cont (+ cont 1))
    cont))

这是一个函数。因此,每次调用此版本的

count
时,该函数都会递增其环境中的
cont
变量。相当于

(define count (make-counter))
© www.soinside.com 2019 - 2024. All rights reserved.