10 August 2013

レキシカルスコープとダイナミックスコープ

その名の通り、レキシカルスコープは字句を解析した時点でスコープが決定し、ダイナミックスコープは実行時に決まる。レキシカルスコープの場合コードの実行前、コード中で変数を宣言した時点の情報からスコープが決まる。たとえばブロック単位のスコープを採用する言語の場合、静的なコードの時点でのブロックの入れ子の状態から、各変数のスコープが決定する。一方ダイナミックスコープは実行時にスタックをたどり変数を探すので、コードの呼び出し順に応じてスコープが決まる。

たとえば次の python のコードをみてみる。

x = 7
def g(): return x
def f():
    x = 9
    return g()
print f()           #=> 7

python はレキシカルスコープを採用する言語なので、print した結果は 7 になる。もしも python がダイナミックスコープだった場合、g() メソッド内の x 変数は、直前の呼び出し元である f() メソッドの x を参照し、print の結果は 9 になる。レキシカルスコープの挙動のほうが直感に沿っているといえるだろう。

近年の言語はほとんどレキシカルスコープを採用しており、emacs lisp や perl の local 変数など一部がダイナミックスコープとなっている。ダイナミックスコープはレキシカルスコープに比べ実装がしやすいというメリットがあるそうだ。

この記事で詳しく解説されていてわかりやすかった。

レキシカルスコープとダイナミックスコープ \| すぐに忘れる脳みそのためのメモ