LoginSignup
0
0

More than 1 year has passed since last update.

レキシカル・バインディングとダイナミック・バインディング

Last updated at Posted at 2023-01-10

年末年始から、An Introduction to Programming in Emacs Lispを読んでいます。
ちょっとつまずいた箇所があったので、まとめようと思います。

先にまとめ

Emacs 27.1でレキシカル・バインディングがデフォルトで有効になりました。
GNUのドキュメントでは、その点カバーできていない部分があるようなので、気をつけよう。

レキシカル・バインディングとダイナミック・バインディング

というか、レキシカルとかダイナミックとかって何?という話もあるので、簡単に。

(setq value 255)

(defun inner ()
  (message "inner> value = %d" value))

(defun outer ()
  (let ((value 0))
    (message "outer> value = %d" value)
    (inner)))

上記は、ダイナミック・バインディングが有効か、レキシカル・バインディングが有効かで動作が変わります。

ここでは、valueと名のついた変数が2つあります。
1つはsetqで設定した、グローバル変数に相当するもの。値は255に束縛しています。
もう1つはlet式内で定義された、outer関数のローカル変数に相当するもの。値は0に束縛しています。

ダイナミックバインディングが有効な場合

上記のコードで、(outer)を評価すると、ミニバッファは以下のように出力します:

outer> value = 0
inner> value = 0

inner> value = 0 とあるとおり、inner関数はローカル変数のvalueにアクセスしています。
outer関数の中で呼び出されたinner関数は、ダイナミック・バインディングにより、実行時に直近にある変数にアクセスしました。一番近くにあったのは、outer 内のローカル変数である value。そのため、ミニバッファの出力は inner> value = 0 となりました。

レキシカル・バインディングが有効な場合

同様にして、ミニバッファは以下のように出力します:

outer> value = 0
inner> value = 255

inner> value = 0 ではなくなりました。レキシカル・バインディングにより、inner関数がアクセスするのは、実行時ではなく、コード記述時点で直近にある変数 value。つまり setq で設定したグローバル変数の value です。

Emacs 27.1からはレキシカル・バインディングがデフォルトで有効に

Emacs 27.1からはレキシカル・バインディングがデフォルトで有効になっています。
明示的にレキシカル・バインディングを有効にするには、(setq lexical-binding t) とします。

lexical-binding  ; => t

An Introduction to Programming in Emacs Lispでは、2023年1月現在、この変更に追従できていないのか、ダイナミック・バインディングがデフォルトと記述がされています (そこで混乱して、この文章をまとめるに至りました)。気をつけんとなぁ、と思います。

In computer science jargon, we would say the binding of a symbol is visible only in functions called in the let form; in Emacs Lisp, the default scoping is dynamic, not lexical. (The non-default lexical binding is not discussed in this manual.)
Prevent confusion (Programming in Emacs Lisp)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0