次: Extent, 前: Variable Scoping, 上: Variable Scoping
Emacs Lispでは、 ローカル変数束縛は無限のスコープ(indefinite scope)です。 つまり、プログラムテキスト上のどの関数からでも、 ある変数束縛を参照できるのです。 つぎの関数定義を考えてみましょう。
(defun binder (x) ;x
は、binder
で束縛 (foo 5)) ;foo
は別の関数 (defun user () ;x
は、user
において『自由』 (list x))
テキスト上のスコープを用いる言語では、
binder
内のx
の束縛を、user
で参照することはできません。
なぜなら、user
は、テキスト上で関数binder
の内側にはないからです。
しかしながら、動的スコープのEmacs Lispでは、
状況に応じて、binder
内で確立したx
の束縛を
user
から参照してもしなくてもよいのです。
binder
をまったく呼び出さずに、直接user
を呼び出したときには、
とにかくみつかったx
の束縛を使うが、
それはbinder
のものではありえない。
foo
をつぎのように定義してbinder
を呼び出したときには、
binder
が作った束縛をuser
で見える。
(defun foo (lose) (user))
foo
をつぎのように定義してbinder
を呼び出したときには、
binder
が作った束縛はuser
では見えない。
(defun foo (x) (user))
ここで、binder
がfoo
を呼び出すと、
foo
はx
を束縛する。
(foo
の束縛はbinder
の束縛を隠す(shadow)という。)
したがって、user
は、binder
の束縛ではなく、
foo
の束縛を参照することになる。
Emacs Lispで動的スコープを使うのは、 テキスト上のスコープの単純な実装は遅いからです。 さらに、すべてのLispシステムは、少なくともオプションとして、 動的スコープを使えるようにする必要があります。 テキスト上のスコープが標準であると、 特定の変数に対して動的スコープを指定する方法が必要になります。 Emacsで両方のスコープを使えるようにしてもよいのですが、 動的スコープだけだと実装がより簡単になります。