レキシカルスコープはコンパイラにどのように役立ちますか? コンパイルや最適化に役立ちますか?
5 に答える
レキシカル スコープはコンパイラと最適化に役立つと思います。ただし、ヘルプの意味によって異なります。
レキシカルまたは静的スコープにより、ローカルで参照された場合、つまりレキシカル コンテキスト内で変数が使用可能であることをコンパイラが証明できます。変数を参照するメソッドのスコープ内にある必要があります。
動的スコープ環境でこれを行うには、すべての呼び出しコンテキストを考慮する必要があります。関数は呼び出しコンテキストも知っているすべての変数を知っているからです。変数を参照できるようにするには、コンパイル時にすべての呼び出しコンテキストを再帰的にバックトラックする必要があります。
これは非常に複雑であるため、コンパイル時に省略され、実行時に例外がスローされます。
ここを参照してください: 対照的に、動的スコープでは、最初にローカル関数を検索し、次にローカル関数を呼び出した関数を検索し、次にその関数を呼び出した関数を検索し、呼び出しスタックを上に検索します。「動的」とは、特定の関数が呼び出されるたびに呼び出しスタックが異なる可能性があるため、関数が呼び出された場所に応じて異なる変数にヒットする可能性があるという点で、変更を指します。
動的スコープでは、最適化を可能にする制約を保証できないため、多くの最適化は不可能です。
これは、ストレージのサイズや表現を保証しない動的言語では特に重要です。
たとえば、動的に型付けされた言語のコンパイラは、ボックス化されたオブジェクトのリンクされたリストを取得し、それを符号なし 8 ビット バイトの配列に置き換えることができます。リストの要素が常に 0 から 255 までの整数であることが証明できる場合です。この種のことは、適切に使用すれば静的スコープで簡単に証明でき、スペースと計算効率の両方を大幅に向上させることができます。
動的変数はデバッグで追跡するのがはるかに難しいため、多くの場合、字句スコープのコードをデバッグする方が簡単です。goto やグローバル変数の使いすぎによって引き起こされる問題と同様に、定義されている可能性のある場所の一種のスパゲッティ コードがあります。
簡単に言うと、字句 (または静的) スコープは言語が静的に型付けされている場合に役立ち、動的スコープは言語が動的に型付けされている場合に役立ちます。
動的スコープでは、変数のスコープは実行時に解決されます。int として宣言された変数が、同じ名前の変数が float 型を持つ別のレキシカル環境で使用されている場合。それらを 2 つの異なる変数と見なすだけでした。つまり、変数は型情報を保持する必要があります。ほとんどの静的型システムでは、型情報はオブジェクト コードにまったく入力されません。プログラムは、型エラーが発生しないことを証明できる場合にのみコンパイルされ、型情報はもちろん必要なくなります。
この理由から、レキシカル スコープを持つ動的言語は、多くの場合、スタックではなくヒープを使用してランタイム情報を割り当てる必要があります。
レキシカル スコープは、コンパイラやコードの最適化には役立ちません。これは言語設計上の決定です。詳細については、この質問を参照してください。