答えて

3

まあ、そこには、プロと詐欺について話し合うウェブサイトがたくさんあるので、私はそこに行かない。

動的スコープに似ているいくつかの機能を持つ面白い言語の1つはXSLTです。 XSLTのテンプレートや変数などはレキシカルスコープですが、XSLTはもちろんXMLに関するもので、コンテキストツリーがグローバルでXPath式が評価されないという意味でxmlツリーの現在の位置が「動的スコープ」ですXSLTのレキシカルスコープによるが、動的評価によると。

7

Mathematicaは、Block構造体を介して、動的にスコープされた別の言語です。これは、実際には数式を扱うときには非常に便利です。それはあなたがatなどの変数はレキシカルスコープた場合、まったく動作しないでしょう

In[1]:= expr = a*t^2 + b*t+ c; 

In[2]:= Block[{a = 1, b = -1, c = 2}, Table[expr, {t, 5}]] 
Out[2]= {2, 4, 8, 14, 22} 

のようなものを書くことができます。特にMathematicaの規則書き換えシステムでうまく動作します。これは、変数が既存の定義を持たない場合には(シンボル式として)評価されません。

MathematicaはModule構造体を使ってレキシカルスコープを偽造することができますが、これは実際には新しい、おそらくユニークなシンボルの形で表現を書き換えます(次のユニークなシンボルが何であるかを予測すれば、ほとんどの場合)。

Block[{x$134 = 4}, 
    Table[x$134 * t, {t, 5}] 

Emacs Lispに、そのライブラリのいずれかで、構築物(実際にLispのマクロ)は、まったく同じトリックを引っ張るlexical-let呼びかけている:これは

Module[{x = 4}, 
    Table[x * t, {t, 5}]] 

はこのようなものに変えることを意味しますレキシカルスコープを偽造する

ELispやMathematicaの偽のレキシカルでは得られない言語をコンパイルするときに、実際のレキシカルスコープにはパフォーマンス上の利点があります。これは、ダイナミック変数とその現在の値の間にマッピングが必要なためです。ルックアップ(ハッシュテーブルやプロパティリストなど)と間接的な追加レイヤーを使用しています。

EDIT:あなただけのレキシカル変数を持っている場合は、することができますスコープを入力して、以前の値が範囲を出た時に復元されていることを保証する上でのグローバル、レキシカル変数の元の値を格納することで、偽の動的スコープ。そのためには、LispのUNWIND-PROTECTfinallyなどのブロックが必要です。私はこれがC++デストラクタを使って行われているのを見てきました。

9

動的にスコープ化された言語を実装する方がずっと簡単です。現在の活動記録/スタックフレームにない変数にアクセスするには、制御リンクの直後にある変数が必要です。静的/字句的なアクセスリンクは必要ないので、スタックフレームを小さくします。

動的変数は、どの変数が使用されるかを知るために実際のスタックフレームがどの順番であるかを知る必要があるため、実行時に「予測できない」可能性があります。この情報は、コードの静的構造を見るだけでは利用できません。プログラムの実際のコールグラフが実装時に予測するのが容易でない場合は、簡単にキャッチできます。なぜ今日のほとんどの言語が静的スコープを持っているのですか(しかし、ほとんどの例外システムは動的です)。

ただし、動的スコープ変数は非常に便利です。たとえば、出力をリダイレクトする場合、動的変数を使用すると、ローカルコードとそこから呼び出されるすべてのコードの標準出力を設定できます。 (Seibelのから)このコモンLispの例で

(let ((*standard-output* *some-other-stream*)) 
(stuff)) 

、標準出力は、(その囲む括弧内)、LET形の期間別のストリームに結合されます。実行がletを離れるとき、それは前にあったものに戻る。良い話し合いのために、http://gigamonkeys.com/book/variables.html Peter Seibelsの無料で優れた本、Practical Common Lispを参照してください。 Seibels自身の言葉で:

動的バインディングは、グローバル変数の管理をはるかに容易にしますが、離れた場所でもアクションを実行できることに注意することが重要です。グローバル変数をバインドするには、2つの距離効果があります。これは、下流のコードの動作を変更する可能性があります。また、下流のコードがスタック上の上位に設定されたバインディングに新しい値を割り当てる可能性があります。動的変数は、これらの特性の一方または両方を利用する必要がある場合にのみ使用してください。

3

ダイナミックスコープは、インタープリタで実装するのが簡単でした。ほとんどの初期のLispインタプリタはダイナミックスコープを使用していました。数年後、レキシカルスコープに利点があることが判明しましたが、最初はほとんどがLispコンパイラで実装されていました。解釈されたコードで動的スコープを実装し、コンパイルされたコードでレキシカルスコープを実装する実装がいくつか登場しました。いくつかは、クロージャを提供するための特別な言語構成を提供していました。 SchemeやCommon LispのようなLispの方言は、解釈されたコードとコンパイルされたコードとの間に違いがないことが必要であり、したがって解釈ベースの実装はレキシカルスコープを実装しなければならなかった。

初期Smalltalkの実装では、ダイナミックスコープが実装されています。あらゆる種類のLispの方言の実装は、動的スコープ(Interlisp、UCI Lisp、Lisp Machine Lisp、MacLispなど)を実装しています。

ほとんどすべての新しいLisp方言は、過去20年の間に、デフォルトで、あるいはもっぱら排他的にレキシカルスコープを使用しています。 Lispをレキシカルスコープで実装する方法については、いくつかの出版物で詳しく説明されているので、レキシカルスコープを使用しないという言い訳はありません。

2

すべてのシェル言語(bash、kshなど)は動的スコープを使用します。

関連する問題