動的スコープ、ダイナミックスコープ()とは、プログラミング言語におけるスコープの一種である。
動的スコープは、実行時の親子関係の子側(呼び出された側)から親側(呼び出し側)のスコープを参照できるスコープである。このとき参照されるのは、親子関係を親側に辿り、より近いブロックにある変数である。以下の疑似コードでは:
A { print x
B { var x call A // Aの中からxを参照することができる
C { var y call A // Aの中からxを参照することはできない
ブロックBから呼び出されたブロックAは、ブロックBで定義されている変数xを参照できる。一方、ブロックCから呼び出されたブロックAは、ブロックBで定義されている変数xは参照できない。
動的スコープは強力な反面、ミスを招きやすいため使用に注意が必要である。例えば以下の疑似コードでは呼び出し元ブロックによって変数の値が変化することを示している。
var x = 123
A { var x = 456 call C // 456と出力される
B { call C // 123と出力される
C { print x // 呼び出し元によって x の値が変わる
言語仕様に動的スコープを持つ言語の例としてはCommon Lisp(特殊変数)やEmacs Lisp、LOGO、Perl(「local」宣言した変数)、Bash(関数内で「local」宣言した変数)などがある。
エクステントとの関係 以上のようにして「動的スコープ」というものの振舞として捉えられているものには、理論的には、スコープとエクステント(生存期間、寿命)との混乱がある。Common Lisp the Language, 2nd Edition では、本来正確には「indefinite scope and dynamic extent」といったように表現されるべきものであって「The term dynamic scope is a misnomer.」といったように書かれている。
静的スコープとの関係 観点によっては、動的スコープは「静的スコープのバグのある実装」のようにも見えなくもない。ネストした関数などにおいて、内側から外側に出ない範囲で、かつ呼び出し階層の途中で名前を横取りされていなければ、静的スコープのように構文的に外側にある変数にアクセスできることになる。
1960年の LISP I の実装が動的スコープだったことについて、ジョン・マッカーシーは後に1979年にそれを振り返って「現代の用語では、静的スコープが望まれていたのに対し、動的スコープが得られた。(In modern terminology, lexical scoping was wanted, and dynamic scoping was obtained.)」と書いている。
参考文献 西尾泰和『コーディングを支える技術 ~成り立ちから学ぶプログラミング作法』
注
関連項目 名前空間