Alguém pode ajudar a explicar este procedimento de esquema
Pergunta
Pergunta:
((lambda (x y) (x y)) (lambda (x) (* x x)) (* 3 3))
Isso foi o primeiro lugar no meio do prazo, eu coloquei "81 9", ele pensou que eu esqueci de cruzar um Lawl, então cruzei 81 e ele vai aww. De qualquer forma, não entendo por que são 81.
Eu entendo o porquê (lambda (x) (* x x)) (* 3 3) = 81
, mas o primeiro lambda eu não entendo o que os valores X e Y estão lá, e o que o [body] (x y)
faz.
Então, eu esperava que alguém pudesse me explicar por que a primeira parte não parece fazer nada.
Solução
Isso precisa de algum recuo para esclarecer
((lambda (x y) (x y))
(lambda (x) (* x x))
(* 3 3))
(lambda (x y) (x y))
; ligarx
comy
como apenas parâmetro.(lambda (x) (* x x))
; Avalie o quadrado de seu parâmetro.(* 3 3)
; Avalie para 9
Portanto, a coisa toda significa: "Chame a função quadrada com o 9 como parâmetro".
Editar: o mesmo poderia ser escrito como
((lambda (x) (* x x))
(* 3 3))
Eu acho que a intenção do exercício é destacar como avaliar um formulário de esquema envolve uma aplicação de função implícita.
Outras dicas
Vejamos isso de novo ...
((lambda (x y) (x y)) (lambda (x) (* x x)) (* 3 3))
Para avaliar um formulário, avaliamos cada parte dele por sua vez. Temos três elementos em nossa forma. Este está na primeira posição (função):
(lambda (x y) (x y))
Este é um segundo elemento de uma forma e um primeiro argumento para a função:
(lambda (x) (* x x))
Último elemento do formulário, portanto, um segundo argumento para a função.
(* 3 3)
A ordem de avaliação não importa neste caso, então vamos começar da esquerda.
(lambda (x y) (x y))
Lambda cria uma função, portanto, isso avalia uma função que leva dois argumentos, x e y, e depois aplica x a y (em outras palavras, chama x com um único argumento y). Vamos chamar isso Ligue para 1.
(lambda (x) (* x x))
Isso avalia uma função que pega um único argumento e retorna um quadrado desse argumento. Então, podemos simplesmente chamar isso quadrado.
(* 3 3)
Isso obviamente avalia para 9.
OK, então, após esta primeira corrida de avaliação, temos:
(call-1 square 9)
Para avaliar isso, chamamos Ligue para 1 com dois argumentos, quadrado e 9. Aplicando Ligue para 1 nos dá:
(square 9)
Já que é isso Ligue para 1 Faz - chama seu primeiro argumento com seu segundo argumento. Agora, quadrado de 9 é 81, que é o valor de toda a expressão.
Talvez traduzir esse código para o Lisp comum ajude a esclarecer seu comportamento:
((lambda (x y) (funcall x y)) (lambda (x) (* x x)) (* 3 3))
Ou ainda mais explicitamente:
(funcall (lambda (x y) (funcall x y))
(lambda (x) (* x x))
(* 3 3))
De fato, esse primeiro Lambda não faz nada útil, pois se resume a:
(funcall (lambda (x) (* x x)) (* 3 3))
que é igual a
(let ((x (* 3 3)))
(* x x))
é igual a
(let ((x 9))
(* x x))
é igual a
(* 9 9)
é igual a 81.
As respostas postadas até agora são boas, então, em vez de duplicar o que eles já disseram, talvez aqui esteja outra maneira de ver o programa:
(define (square x) (* x x))
(define (call-with arg fun) (fun arg))
(call-with (* 3 3) square)
Ainda parece estranho?