Может ли кто-нибудь помочь объяснить эту схему процедуры
Вопрос
Вопрос:
((lambda (x y) (x y)) (lambda (x) (* x x)) (* 3 3))
Это было № 1 в промежуточном экзамене, я поставил "81 9", он подумал, что я забыл вычеркнуть один из лоула, поэтому я вычеркнул 81, и он воскликнул: "ого!"В любом случае, я не понимаю, почему сейчас 81 год.
Я понимаю, почему (lambda (x) (* x x)) (* 3 3) = 81
, но первая лямбда, я не понимаю, какие там значения x и y, и что [body] (x y)
делает.
Поэтому я надеялся, что кто-нибудь сможет объяснить мне, почему кажется, что первая часть ничего не делает.
Решение
Для уточнения этого требуется некоторое отступление
((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 в качестве параметра".
Редактировать:То же самое можно было бы записать как
((lambda (x) (* x x))
(* 3 3))
Я предполагаю, что цель упражнения состоит в том, чтобы подчеркнуть, как оценка формы схемы включает в себя применение неявной функции.
Другие советы
Давайте посмотрим на это снова ...
((lambda (x y) (x y)) (lambda (x) (* x x)) (* 3 3))
Чтобы оценить форму, мы оцениваем каждую ее часть по очереди. У нас есть три элемента в нашей форме. Этот находится на первой (функциональной) позиции:
(lambda (x y) (x y))
Это второй элемент формы и первый аргумент функции:
(lambda (x) (* x x))
Последний элемент формы, поэтому второй аргумент функции.
(* 3 3)
В этом случае порядок оценки не имеет значения, поэтому давайте начнем с левой стороны.
(call-1 square 9)
Лямбда создает функцию, поэтому она оценивает функцию, которая принимает два аргумента, x и y, а затем применяет x к y (другими словами, вызывает x с одним аргументом y). Давайте назовем это call-1 .
(square 9)
Это вычисляет функцию, которая принимает один аргумент и возвращает квадрат этого аргумента. Таким образом, мы можем просто назвать это квадрат .
<*>Это, очевидно, оценивается в 9 .
Хорошо, после первого запуска оценки мы имеем:
<*>Чтобы оценить это, мы вызываем call-1 с двумя аргументами: квадрат и 9 . Применение call-1 дает нам:
<*>Так как call-1 делает именно это, он вызывает свой первый аргумент со вторым аргументом. Теперь квадрат 9 равен 81 , что является значением всего выражения.
Возможно, перевод этого кода на 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))
Действительно, эта первая лямбда не делает ничего полезного, поскольку она сводится к:
(funcall (lambda (x) (* x x)) (* 3 3))
который равен
(let ((x (* 3 3)))
(* x x))
равно
(let ((x 9))
(* x x))
равно
(* 9 9)
равно 81.
Ответы, опубликованные до сих пор, являются хорошими, поэтому вместо того, чтобы дублировать то, что они уже сказали, возможно, вот другой способ взглянуть на программу:
(define (square x) (* x x))
(define (call-with arg fun) (fun arg))
(call-with (* 3 3) square)
Это все еще выглядит странно?