次: 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で両方のスコープを使えるようにしてもよいのですが、 動的スコープだけだと実装がより簡単になります。