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.

Foi útil?

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)); ligar x com y 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?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top