質問
質問:
((lambda (x y) (x y)) (lambda (x) (* x x)) (* 3 3))
これは中期で1位だったので、「81 9」と入力しました。彼は私が1つの芝生を越えることを忘れていたと思ったので、私は81を越えると彼はawwになります。とにかく、なぜ81なのかわかりません。
(lambda(x)(* xx))(* 3 3)= 81
の理由はわかりますが、最初のラムダについてはxとyの値が何であり、何が [body](xy)
はそうします。
だから、最初の部分が何もしないように見える理由を誰かが説明してくれることを望んでいました。
解決
これを明確にするためにインデントが必要です
((lambda (x y) (x y))
(lambda (x) (* x x))
(* 3 3))
-
(lambda(x y)(x y))
;パラメータとしてy
を使用してx
を呼び出します。 -
(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))
フォームを評価するには、フォームの各部分を順番に評価します。フォームには3つの要素があります。これは最初の(関数)位置にあります:
(lambda (x y) (x y))
これはフォームの2番目の要素であり、関数の最初の引数です。
(lambda (x) (* x x))
フォームの最後の要素なので、関数の2番目の引数。
(* 3 3)
この場合、評価の順序は重要ではないため、左から始めましょう。
(call-1 square 9)
Lambdaは関数を作成するため、xとyの2つの引数を取る関数に評価され、xをyに適用します(つまり、1つの引数yでxを呼び出します)。これを call-1 と呼びましょう。
(square 9)
これは、単一の引数を取り、この引数の2乗を返す関数に評価されます。したがって、これを正方形と呼ぶことができます。
<*>これは明らかに 9 と評価されます。
OK、この評価の最初の実行後:
<*>これを評価するために、2つの引数 square と 9 を指定して call-1 を呼び出します。 call-1 を適用すると、次のことがわかります。
<*>それが call-1 の動作なので、最初の引数を2番目の引数で呼び出します。現在、 9 の2乗は 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)
まだ奇妙に見えますか?