Может ли кто-нибудь помочь объяснить эту схему процедуры

StackOverflow https://stackoverflow.com/questions/223468

  •  03-07-2019
  •  | 
  •  

Вопрос

Вопрос:

((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)

Это все еще выглядит странно?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top