2
 (define make (lambda (x) (lambda (y) (cons x (list y)))))

 (let ((x 7)
       (p (make 4)))
   (cons x (p 0)))

私はSchemeと関数型プログラムに慣れていないので、プログラムをウォークスルーするのは少し不格好ですが、ディープバインディングを使用すると、このプログラムは(7 4 0)に戻ります。理にかなっています。このプログラムは浅いバインディングを使用して何をしますか?これはばかげているように聞こえるかもしれませんが、短所と一致するpは再定義ですか?したがって、その場合、(7 0)を返しますか?

基本的にはディープバインディングとシャローバインディングの概念は理解していますが、Schemeを見ると、あまり慣れていないので、混乱しているような気がします。

4

2 に答える 2

3

ディープバインディングまたはシャローバインディングは実装手法であり、プログラム内からは観察できません。プログラマーにとっての違いは、字句スコープと動的スコープのルールの違いですが、どちらも2つの手法のいずれかで実装できます(つまり、一方の概念はもう一方の概念とは関係ありません)。

深いまたは浅いとは、特定の外部スコープ変数のバインディングを保持するためのスタックフレームの選択を指します。ディープバインディングでは、変数のレコードを保持している正しいフレームが入力されるまで、アクセスされるフレームのチェーンがあります。浅いバインディングでは、すべてのバインディングが1つの浅い環境に存在します。「ルート変更」も参照してください(これは、字句スコープの浅いバインディング実装のコンテキストでのみ意味があります)。

あなたの特定の質問に対して、字句スコープのルールの下では、コードは動的(7 4 0)に返されます- 、呼び出しはバインディングの動的スコープ内で行われるため(補足として、と同じです):(7 7 0)((lambda(y) (list x y)) 0)x=7(cons x (list y))(list x y)

x = 7
p = (lambda (y) (list x y))      ; x=4 is unused, in p=(make 4)
(cons 7 (p 0)) == (list 7 7 0)   ; 'x' in this line and in lambda body for p
                                 ;   both refer to same binding that is
                                 ;   in effect, i.e. x=7

NB同じ用語(深い/浅いバインディング)が他の言語で使用されており、現在はまったく異なる意味を持っています(それらはそこでのスコープ規則と関係があります)。これは私が完全に理解することを気にしません。この答えはSchemeの文脈で与えられます。

参照:Baker、Henry G. Jr.、1977年によるLISP1.5の浅いバインディング。

于 2013-02-22T00:39:08.997 に答える
0

スキームが字句スコープであることを念頭に置いて、スコープ(字句/動的スコープおよび深い/浅いバインディングについて言及)に関する議論については、このウィキペディアの記事を参照してください。ネスの答えは追加情報を提供します。今のところ、このコードスニペットで何が起こっているかを段階的に見ていきましょう。

; a variable called x is defined and assigned the value 7
(let ((x 7)
; make is called and returns a procedure p, inside its x variable has value 4
      (p (make 4)))
; 7 is appended at the head of the result of calling p with y = 0
  (cons x (p 0)))

=> '(7 4 0)

2行目では、によって返されるラムダにクロージャが作成され、内部makeの変数に値が割り当てられることに注意してください。Schemeは字句スコープであるため、これは外部とは何の関係もありません。x4xx

前の段落で述べたように、最後の行は再定義ではありません。x内部は式で定義されたmakeものとは異なります。xlet

于 2013-02-21T22:41:34.903 に答える