3

问题:

((lambda (x y) (x y)) (lambda (x) (* x x)) (* 3 3))

这是期中考试的第一名,我写了“81 9”,他以为我忘了划掉一个法律,所以我划掉了 81,然后他就哭了。无论如何,我不明白为什么是81。

我明白为什么(lambda (x) (* x x)) (* 3 3) = 81,但是第一个 lambda 我不明白 x 和 y 值是什么,以及它们的[body] (x y)作用。

所以我希望有人能向我解释为什么第一部分似乎没有任何作用。

4

4 回答 4

9

这需要一些缩进来澄清

((lambda (x y) (x y))
 (lambda (x) (* x x))
 (* 3 3))
  • (lambda (x y) (x y)); 仅作为参数调用xy
  • (lambda (x) (* x x)); 计算为其参数的平方。
  • (* 3 3); 评价为 9

所以整个事情的意思是:“以 9 为参数调用 square 函数”。

编辑:同样的事情可以写成

((lambda (x) (* x x))
 (* 3 3))

我想这个练习的目的是强调评估方案形式如何涉及隐式函数应用。

于 2008-10-21T21:00:04.673 回答
6

让我们再看看这个...

((lambda (x y) (x y)) (lambda (x) (* x x)) (* 3 3))

为了评估一个表格,我们依次评估它的每个部分。我们的表单中有三个元素。这个位于第一个(功能)位置:

(lambda (x y) (x y))

这是表单的第二个元素和函数的第一个参数:

(lambda (x) (* x x))

表单的最后一个元素,因此是函数的第二个参数。

(* 3 3)

在这种情况下,评估顺序无关紧要,所以让我们从左边开始。

(lambda (x y) (x y))

Lambda 创建了一个函数,因此它计算为一个接受两个参数 x 和 y 的函数,然后将 x 应用于 y(换句话说,使用单个参数 y 调用 x)。我们称之为call-1

(lambda (x) (* x x))

这计算为一个接受单个参数并返回此参数的平方的函数。所以我们可以称之为square

(* 3 3)

这显然评估为9

好的,所以在第一次评估之后,我们有:

(call-1 square 9)

为了评估这一点,我们调用call-1并带有两个参数square9。应用call-1给我们:

(square 9)

因为这就是call-1所做的 - 它用它的第二个参数调用它的第一个参数。现在, 9的平方是81,这是整个表达式的值。

于 2008-10-21T21:40:52.470 回答
2

也许将该代码翻译成 Common Lisp 有助于澄清其行为:

((lambda (x y) (funcall x y)) (lambda (x) (* x x)) (* 3 3))

或者更明确地说:

(funcall (lambda (x y) (funcall x y))
         (lambda (x) (* x x))
         (* 3 3))

事实上,第一个 lambda 并没有做任何有用的事情,因为它归结为:

(funcall (lambda (x) (* x x)) (* 3 3))

这等于

(let ((x (* 3 3)))
  (* x x))

等于

(let ((x 9))
  (* x x))

等于

(* 9 9)

等于 81。

于 2008-10-21T23:22:18.430 回答
1

到目前为止发布的答案都很好,所以与其重复他们已经说过的话,也许这是您可以查看该程序的另一种方式:

(define (square x) (* x x))

(define (call-with arg fun) (fun arg))

(call-with (* 3 3) square)

看起来还是很奇怪吗?

于 2008-10-22T02:48:53.347 回答