问题:
((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)
的作用。
所以我希望有人可以向我解释为什么第一部分似乎没有做任何事情。
答案 0 :(得分:9)
这需要一些缩进来澄清
((lambda (x y) (x y))
(lambda (x) (* x x))
(* 3 3))
(lambda (x y) (x y))
;以x
为唯一参数调用y
。(lambda (x) (* x x))
;评估其参数的平方。(* 3 3)
;评估为9 所以整个意思是:“用9作为参数调用square函数。”
编辑:同样的事情可以写成
((lambda (x) (* x x))
(* 3 3))
我想这个练习的目的是强调评估方案表单如何涉及隐式函数应用程序。
答案 1 :(得分: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)
为了对此进行评估,我们使用两个参数 square 和 9 调用 call-1 。应用 call-1 会给我们:
(square 9)
因为那是 call-1 所做的 - 它用第二个参数调用它的第一个参数。现在, 9 的平方是 81 ,这是整个表达式的值。
答案 2 :(得分: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。
答案 3 :(得分:1)
到目前为止发布的答案都很好,所以不是重复他们已经说过的内容,也许这是另一种你可以看到该程序的方式:
(define (square x) (* x x))
(define (call-with arg fun) (fun arg))
(call-with (* 3 3) square)
它看起来仍然很奇怪吗?