这是来自SICP Video Lectures,第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))))
第二个lambda中的x
在AVERAGE-DAMP中做了什么以及它是如何被访问的?我不明白究竟是什么传递给它。
答案 0 :(得分:3)
(DEFINE AVERAGE-DAMP
(LAMBDA f
(LAMBDA x (AVERAGE (f x) x))))
关于这一点的棘手问题是在这里传递了一个函数。
average-damp是f
的函数,被定义为x
的函数,被定义为f(x)
(“f of x”)和{{1}的平均值}}
换句话说,average-damp是一个接受另一个函数的函数,在它周围包装一个函数,然后返回这个新函数。
如果您有任何机会熟悉JavaScript,这可能有所帮助:
x
现在想想,以下是什么?
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 * 2和x的平均值。
换句话说,就像:
x
如果你有:
function (x) {
return average(x * 2, x);
}
将一个函数包装在函数内部就是你的lisp片段所发生的事情。
编辑:出于好奇,我在JavaScript中完全实现了定点sqrt方法:http://jsfiddle.net/tXDQL/。
答案 1 :(得分:1)
x
的值将是fixed-point
传递给函数的参数。
现在你没有提供fixed-point
的定义,但是从我想象的名称,它将首先用参数1
调用函数(因为这是第二个给出的)参数fixed-point
)然后继续以前一个结果作为参数调用该函数,直到结果与前一个结果相同。
因此,第一次调用x
将为1,第二次调用为(average (f 1) 1)
,第三次调用为(average (f (average (f 1) 1)) (average (f 1) 1))
,依此类推。
答案 2 :(得分:1)
AVERAGE-DAMP
被定义为一个函数(lambda),当给定参数f
时,返回另一个函数(另一个lambda),当给定参数x
时,计算x
和f(x)
的平均值,其中f
是之前收到的函数。
然后,在SQRT
中,注意如何使用一个参数调用AVERAGE-DAMP
(恰好是一个函数,一个lambda)。这会将调用转换为另一个函数(AVERAGE-DAMP
中的第二个lamda),给定一个值,将给定的函数(LAMBDA Y (/ X Y))
计算为给定值。 FIXED-POINT
函数将负责获取该函数并为其认为合适的每个值评估先前的函数。
答案 3 :(得分:0)
(DEFINE (SQRT X)
(FIXED-POINT
(AVERAGE-DAMP (LAMBDA Y (/ X Y)))
1))
(DEFINE AVERAGE-DAMP
(LAMBDA F
(LAMBDA X (AVERAGE (F X) X))))
起初看起来可能会让人感到困惑,我在学习的过程中试图帮助我澄清这一点是为了取代" X"在" Y"的AVERAGE-DAMP中。这将有助于区分" 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(/ X Y)),
然后(F Y) - > (/ X Y),
然后(AVERAGE-DAMP(LAMBDA Y(/ X Y))) - > (LAMBDA Y(AVERAGE(/ X Y)Y))