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

时间:2011-11-28 03:25:43

标签: lisp scheme sicp

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

2 个答案:

答案 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函数捕获,它可以对它做任何事情,但是从其他任何地方都看不到,因为它在我们定义的范围中。