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

Lisp SICP练习3.8-为什么程序有效?(我认为这与环境有关),lisp,scheme,sicp,Lisp,Scheme,Sicp,SICP中的练习3.8描述为: 当我们在第1.1.3节中定义评估模型时,我们说 计算表达式的第一步是计算其 子表达式。但我们从来没有指定 应计算子表达式(例如,从左到右或从右到右 左)。当我们引入赋值时,参数的顺序 对一个程序进行评估会对结果产生影响。 定义一个简单的过程f,这样计算(+(f0)(f1))将 如果+的参数从左到右求值,但 如果参数从右向左求值,则返回1 我编写了过程f,这样如果我先调用(fx),每当我再次调用f时,它总是返回x。但我不知道为什么它会起作用。我写的程序是: (def

SICP中的练习3.8描述为:

当我们在第1.1.3节中定义评估模型时,我们说 计算表达式的第一步是计算其 子表达式。但我们从来没有指定 应计算子表达式(例如,从左到右或从右到右 左)。当我们引入赋值时,参数的顺序 对一个程序进行评估会对结果产生影响。 定义一个简单的过程f,这样计算(+(f0)(f1))将 如果+的参数从左到右求值,但 如果参数从右向左求值,则返回1

我编写了过程
f
,这样如果我先调用
(fx)
,每当我再次调用
f
时,它总是返回
x
。但我不知道为什么它会起作用。我写的程序是:

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

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

第一次用X调用它时,它将
s
设置为
X
,并返回它。下次,由于
s
不再是
-1
,它将始终返回
s
,这是第一次调用中保存的
x
的值

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

有一件很重要的事,当你使用(定义f……)而f周围没有括号时,你定义的是一个值,“body”只计算一次。因此,可变值只初始化一次。它也被得到的lambda函数捕获,它可以用它做任何事情,但从其他任何地方都看不到,因为它在我们的定义范围内。

它不是创建了一个新的环境,所以当我调用(f 10)时,s被设置为-1吗?@Bingo:no,当调用
f
时,不会创建新的环境。但是
f
的主体是在
f
附加到的环境中计算的,该环境包含以前调用的
s
。我想我明白了。因为f的主体是lambda部分,所以s的值是f所在环境的一部分。@Bingo:
f
只是一个名称,一个对对象的引用。该对象是一个函数(a
lambda
),它是在
s
所属的某个环境中创建的。谢谢,我现在知道它的确切含义了。还有另一种编写代码的方法可能更清楚:(定义f((lambda(s)(lambda(x)(if(=s-1)(begin(set!sx)s))s))-1)),因此lambda(s)(…)是一个没有名称的对象。例如,在账簿的银行示例中的“makedraw”。而f类似于
中的W(定义W(makedraw-1))