2

这是来自 SICP Video Lectures,Lecture 2a 大约 39:51 左右。

(DEFINE (SQRT X)
   (FIXED-POINT
      (AVERAGE-DAMP (LAMBDA Y (/ X Y)))
      1)) 

(DEFINE AVERAGE-DAMP
   (LAMBDA f
      (LAMBDA x (AVERAGE (f x) x))))

x第二个 lambda 在 AVERAGE-DAMP 中做了什么以及如何访问它?我不明白到底传递给它的是什么。

4

4 回答 4

3
(DEFINE AVERAGE-DAMP
   (LAMBDA f
      (LAMBDA x (AVERAGE (f x) x))))

棘手的事情是这里正在传递一个函数。

average-damp 是 的函数f定义为 的函数x定义为f(x)("f of x") 和的平均值x

换句话说,average-damp 是一个函数,它接受另一个函数,将一个函数包裹在它周围,然后返回这个新函数。

如果您有机会熟悉 JavaScript,这可能会有所帮助:

function average(a, b) {
    return (a + b)/2;
}

function averageDamp(f) {
    return function(x) {
        return average(f(x), x);
    }
}

所以现在想一想,下面是什么?

var something = averageDamp(function (c) { return c * 2 });

something是一个函数,它接受一个参数 ,x并返回 x * 2 和 x 的平均值。

换句话说,它就像:

function (x) {
    return average(x * 2, x);
}

如果你有:

var something = averageDamp(function (c) { return c * 2 });
something(5); //average(5*2, 5) = (10 + 5) / 2

将函数包装在函数内部就是您的 lisp 代码段所发生的事情。

编辑:出于好奇,我在 JavaScript 中完全实现了定点 sqrt 方法:http: //jsfiddle.net/tXDQL/

于 2012-05-28T10:14:18.673 回答
1
(DEFINE (SQRT X)
   (FIXED-POINT
      (AVERAGE-DAMP (LAMBDA Y (/ X Y)))
      1)) 

(DEFINE AVERAGE-DAMP
   (LAMBDA F
      (LAMBDA X (AVERAGE (F X) X))))

起初可能看起来令人困惑,我在学习时试图帮助我澄清这一点的是用“Y”替换 AVERAGE-DAMP 中的“X”。所以这将有助于区分“X”作为 SQRT 中的参数。

(DEFINE (SQRT X)
   (FIXED-POINT
      (AVERAGE-DAMP (LAMBDA Y (/ X Y)))
      1)) 

(DEFINE AVERAGE-DAMP
   (LAMBDA F
      (LAMBDA Y (AVERAGE (F Y) Y))))

所以这里发生的是:
F -> (LAMBDA Y (/XY)),
然后是 (FY) -> (/XY),
然后是 (AVERAGE-DAMP (LAMBDA Y (/XY))) -> (LAMBDA Y (AVERAGE) (/ XY) Y))

于 2012-07-04T03:33:48.120 回答
1

的值x将是fixed-point传递给函数的参数。

现在您没有提供 的定义fixed-point,但是从我想象的名称来看,它将首先使用参数调用函数1(因为这是作为 的第二个参数给出的fixed-point),然后将继续使用其调用函数之前的结果作为参数,直到结果与之前的结果相同。

所以第一次调用x是 1,第二次调用是(average (f 1) 1),第三次调用是 1,(average (f (average (f 1) 1)) (average (f 1) 1))以此类推。

于 2012-05-28T10:15:52.873 回答
1

AVERAGE-DAMP只是定义为一个函数(一个 lambda),当给定一个参数时f,它返回另一个函数(另一个 lambda),当给定一个参数时x计算和的平均值xf(x)其中f是先前接收到的函数。

然后,在 中SQRT,注意如何AVERAGE-DAMP使用一个参数(恰好是一个函数,一个 lambda)调用它。这会将调用转换为另一个函数( 中的第二个 lamda AVERAGE-DAMP),给定一个值,将给定函数评估(LAMBDA Y (/ X Y))为给定值。该FIXED-POINT函数将负责处理该函数并为它认为合适的每个值评估前一个函数。

于 2012-05-28T10:16:59.270 回答