SICP中的练习3.8被描述为打击:
当我们在第1.1.3节中定义评估模型时,我们说过 评估表达式的第一步是评估它 子表达式。但我们从未指定过的顺序 应评估子表达式(例如,从左到右或从右到右) 剩下)。当我们引入赋值时,参数的顺序 对程序进行评估可以对结果产生影响。 定义一个简单的过程f,以便评估(+(f 0)(f 1)) 如果从左到右计算+的参数,则返回0但是 如果从右到左计算参数,则返回1.
我编写了程序f
,这样如果我先调用(f x)
,只要再次调用x
,它就会始终返回f
。但我不确切知道它为什么会起作用。我写的程序是:
(define f
(let ((s -1))
(lambda (x)
(if (= s -1)
(begin (set! s x)
s)
s))))
答案 0 :(得分:2)
将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
>
答案 1 :(得分:0)
有一件重要的事情,当你使用(定义f .......)没有括号围绕f时,你要定义一个值,其中“body”只被评估一次。因此,可变值仅初始化一次。它也可以通过生成的lambda函数捕获,它可以对它做任何事情,但是从其他任何地方都看不到,因为它在我们定义的范围中。