SICP 练习 3.8 - 为什么该程序有效? (我认为这与环境有关)

发布于 2024-12-18 10:37:34 字数 558 浏览 2 评论 0原文

SICP中的练习3.8描述如下:

当我们在1.1.3节定义评估模型时,我们说 计算表达式的第一步是计算它的值 子表达式。但我们从未指定过顺序 应该评估子表达式(例如,从左到右或从右到 左边)。当我们引入赋值时,参数的顺序 对程序进行评估可能会对结果产生影响。 定义一个简单的过程 f,使得计算 (+ (f 0) (f 1)) 将 如果 + 的参数是从左到右计算的,则返回 0,但是 如果从右到左计算参数,将返回 1。

我编写了过程 f,这样如果我先调用 (fx),那么每当我调用 f< 时,它总是返回 x /代码> 再次。但我不知道它为什么有效。我写的程序是:

(define f
  (let ((s -1))
    (lambda (x)
      (if (= s -1)
          (begin (set! s x)
                 s)
           s))))

The exercise 3.8 in the SICP is described as blow:

When we defined the evaluation model in section 1.1.3, we said that
the first step in evaluating an expression is to evaluate its
subexpressions. But we never specified the order in which the
subexpressions should be evaluated (e.g., left to right or right to
left). When we introduce assignment, the order in which the arguments
to a procedure are evaluated can make a difference to the result.
Define a simple procedure f such that evaluating (+ (f 0) (f 1)) will
return 0 if the arguments to + are evaluated from left to right but
will return 1 if the arguments are evaluated from right to left.

And I wrote the procedure f so that if I call (f x) first, it will always return x whenever I call f again. But I do not know exactly why it works. The procedure I wrote is:

(define f
  (let ((s -1))
    (lambda (x)
      (if (= s -1)
          (begin (set! s x)
                 s)
           s))))

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

你怎么敢 2024-12-25 10:37:35

s 视为仅与您的过程绑定的特殊变量,在调用之间保留其值。由于您正在经历 SICP,因此应该清楚它是附加到 f 的过程所在环境的一部分。

第一次使用某些 X 调用它时,它会设置 sx 并返回它。下次,由于 s 不再是 -1,因此它将始终返回 s,即 x 的值code> 保存在第一次调用中。

> (f 42)  ; s is -1, so 42 is saved into it and returned
42
> (f 10)  ; is is 42, so the 'else' branch of the 'if' is taken
          ; and s is returned without looking at x
42
> (f 20)
42
> 

Think of s as a special variable tied just to your procedure, keeping its value between its invocations. Since you're going through SICP it should be clear that it's part of the environment that the procedure attached to f lives in.

First time it's called with some X, it sets s to x and returns it. Next time, since s is no longer -1, it will just always return s, which is the value of x saved in the first call.

> (f 42)  ; s is -1, so 42 is saved into it and returned
42
> (f 10)  ; is is 42, so the 'else' branch of the 'if' is taken
          ; and s is returned without looking at x
42
> (f 20)
42
> 
檐上三寸雪 2024-12-25 10:37:35

有一件重要的事情,当您使用 (define f .......) 而不将 f 括起来时,您正在定义一个 ,其中“body”仅被评估一次。因此,可变值仅初始化一次。它也被生成的 lambda 函数捕获,该函数可以用它做任何事情,但从其他任何地方都不可见,因为它在我们定义的范围内。

There is one important thing, when you use (define f .......) without brackets around f, you're defining a value, which "body" is evaluated only once. Therefore, mutable value is initialized only once. And it's also captured by the resulting lambda function, that can do anything with it, but not visible from anywhere else, because it's inside the scope of our definition.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文