9

動的スコープを使用する言語でクロージャーを許可することに危険がある理由を理解していると思います。つまり、問題なく変数を閉じられるように見えますが、読み込もうとすると、グローバル スタックの一番上にある値しか取得できません。他の関数がその間に同じ名前を使用すると、これは危険な場合があります。

他の微妙な点を見逃していませんか?

4

2 に答える 2

8

私はこれに答えるのに何年も遅れていることに気づきました、しかし私はウェブ検索をしている間にこの質問に出くわしました、そして私はここに投稿されたいくつかの誤った情報を訂正したかったです。

「クロージャ」とは、コードと、そのコード内の自由変数のバインディングを提供する環境の両方を含む呼び出し可能なオブジェクトを意味します。その環境は通常、字句環境ですが、動的環境にできない技術的な理由はありません。

秘訣は、特定の値ではなく、環境全体でコードを閉じることです。これはLisp1.5が行ったことであり、MACLispが「下向きのfunargs」に対して行ったことでもあります。

Lisp 1.5がこれをどのように行ったかは、http://www.softwarepreservation.org/projects/LISP/bookでLisp1.5のマニュアルを読むことで確認できます。

付録Bで、evalがFUNCTIONを処理する方法と、applyがFUNARGを処理する方法に特に注意してください。

http://c2.com/cgi/wiki?DynamicClosureから、動的クロージャを使用したプログラミングの基本的なフレーバーを取得できます。

実装の問題の詳細については、ftp: //publications.ai.mit.edu/ai-publications/pdf/AIM-199.pdfから入手できます。

最新の動的スコープ言語は通常、浅いバインディングを使用します。この場合、各変数の現在の値は1つのグローバルな場所に保持され、関数呼び出しは古い値をスタックに保存します。浅いバインディングで動的クロージャを実装する1つの方法は、http: //www.pipeline.com/~hbaker1/ShallowBinding.htmlで説明されています。

于 2012-06-01T22:39:12.240 に答える
7

はい、それが基本的な問題です。「クロージャ」という用語は「字句クロージャ」の略ですが、定義上、その字句スコープをキャプチャします。動的スコープの言語で物事を別の名前で呼びますLAMBDA。ラムダは、返そうとしない限り、動的スコープの言語で完全に安全です。

(興味深い思考実験のために、Emacs Lispで動的にスコープされたラムダを返す問題とCでスタックに割り当てられた変数への参照を返す問題を比較し、Schemeでは両方が不可能である方法を比較してください。)

昔、動的スコープを持つ言語が今日よりもはるかにまれであったとき、これはfunargs問題として知られていました。あなたが言及する問題は上向きのfunargs問題です。

于 2010-09-10T01:42:57.153 に答える