You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scheme中set!修改let变量及两种计数器实现差异解析

Scheme 计数器实现的差异解惑

背景

在自学MIT 6.5151课程过程中,我完成了这些阅读任务:

  • 按ps0要求读完SICP第1至2.1章
  • 参照CS 61A笔记阅读了SICP 2.2.1章
  • 读完《Software Design for Flexibility》(简称SDF)的序言、第1章,以及部分Scheme附录

问题描述

在SDF的Scheme附录里看到一个用set!实现计数器的示例:

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

定义c1、c2之后,两个计数器拥有各自独立的局部状态,调用(c1)会持续返回递增的数值。

我自己写了一段类似的代码:

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

但在MIT-Scheme里每次执行((count)),结果都是1。当时我疑惑,是不是因为每次调用((count))都会生成一个新的lambda实例?

问题解析(结合SICP第3.2章内容)

后来读完SICP第3.2章,我终于搞懂了:

  • 原示例中,(make-counter)被调用一次后,会返回一个绑定了特定环境的lambda(比如(define c1 (make-counter))),这个环境里的count初始值是0。之后每次调用(c1),都是在同一个环境里修改count的值,所以能实现持续递增。
  • 而我写的count过程,每次调用(count)都会构造一个全新的环境,其中的cont被重新初始化为0,然后返回绑定这个新环境的lambda。当执行((count))时,相当于先调用count生成新环境和lambda,再执行这个lambda——每次都是在全新的环境里把0加1,结果自然一直是1。这个逻辑和SICP里的(make-withdraw 100)是类似的,每次调用构造新环境,状态无法持续保留。

内容的提问来源于stack exchange,提问作者An5Drama

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 19:37:46