グローバル変数は、 明示的に新しい値で置き換えない限り存続する値を持ちます。 一時的にしか存在しない変数値、 つまり、プログラムのある部分を完了するまでのみ存在する変数値を 作れると便利なことがあります。 このような値をローカル(local、局所的)と呼び、 そのように使われる変数をローカル変数(local variables)と呼びます。
たとえば、関数を呼び出したとき、その引数変数は、
関数を抜けるまで存続する新たなローカルな値を受け取ります。
スペシャルフォームlet
は、指定した変数の新たなローカル値を
明示的に確立します。
これらはフォームlet
を抜けるまで存続します。
ローカル値を確立すると、 変数の以前の値(あるいは値がないこと)を保存します。 ローカル値の存続期間が終了すると、以前の値を復元します。 この期間は、以前の値を隠して(shadowed)いて 以前の値は見えません。 グローバル値でもローカル値でも隠せます(see Scope)。
変数がローカルなときに(setq
などで)その変数を設定すると、
ローカル値を置き換えます。
隠されているグローバル値や以前のローカル値を変更しません。
このふるまいをモデル化するために、
変数のローカル値に加えて変数のローカル束縛(local binding)を
考えます。
ローカル束縛とは、ローカル値を保持する概念的な場所です。
関数やlet
などのスペシャルフォームに入るたびに
ローカル束縛を作成します。
関数やフォームlet
から抜けるとローカル束縛を削除します。
ローカル束縛が存続する限り、変数の値はそこに保持されています。
ローカル束縛が存在するときにsetq
やset
を使うと、
ローカル束縛の中に別の値を格納します。
新たな束縛を作るのではありません。
グローバル値を保持する概念的な場所を グローバル束縛(global binding)ともいいます。
変数には一度に複数のローカル束縛がありえます
(たとえば、同じ変数を束縛する入れ子になったフォームlet
があるとき)。
そのような場合、既存のもっとも最近に作成されたローカル束縛が、
変数の現在の束縛(current binding)です。
(この規則を動的スコープ(dynamic scoping)と呼びます。
see Variable Scoping)
ローカル束縛がまったくなければ、変数のグローバル束縛が現在の束縛です。
現在の束縛のことを強調して既存の最ローカル束縛と呼ぶこともあります。
シンボルの通常の評価では、その現在の束縛の値を返します。
スペシャルフォームlet
やlet*
は、
ローカル束縛を作るためにあります。
このスペシャルフォームは、bindingsに従って変数を束縛し、 formsのすべてをテキスト上の順に評価する。
let
フォームは、formsの最後のフォームの値を返す。bindingsのおのおのは、(i)シンボルであるか、 (ii)フォーム
(
symbol value-form)
のリストである。 前者は、シンボルにnil
を束縛する。 後者は、symbolにvalue-formの評価結果を束縛する。 value-formを省略するとnil
を使う。bindingsのvalue-form群すべてを現れる順に評価してから、 シンボルにそれらの値を束縛する。 例をつぎに示す。
Z
は、Y
の古い値2に束縛され、Y
の新しい値1ではない。(setq Y 2) ⇒ 2 (let ((Y 1) (Z Y)) (list Y Z)) ⇒ (1 2)
このスペシャルフォームは
let
に似ているが、 変数のローカル値を計算し終えた直後にその変数を束縛し、 つぎの変数のローカル値の計算に進む。 したがって、bindings内の式では、このlet*
フォーム内で まえにあるシンボルを参照できる。 つぎの例を上のlet
の例と比較してほしい。(setq Y 2) ⇒ 2 (let* ((Y 1) (Z Y)) ; 設定し終えたばかりのY
の値を使う (list Y Z)) ⇒ (1 1)
以下にローカル束縛を作成するその他の機能の完全な一覧をあげておきます。
変数は、バッファローカルな束縛(see Buffer-Local Variablesや フレームローカルな束縛(see Frame-Local Variables)を持つことができます。 少数の変数は、端末にローカルな束縛(see Multiple Displays) を持つこともできます。 この種の束縛は普通のローカル束縛と同じように働きますが、 これらはEmacsの『どの部分』にいるかに依存したローカル化であり、 時間的なローカル化ではありません。
この変数は、(
"Variable binding depth exceeds max-specpdl-size"
を 伴った)エラーを通知するまでに許される、 ローカル変数束縛とunwind-protect
による後始末(see Nonlocal Exits)の 全体の個数の制限を定義する。この制限、および、これを超えたときのエラーは、 不正に定義された関数によってLispが無限に再帰することを防止する 1つの方法である。
デフォルト値は600である。 Lispデバッガに入ったとき、 制限に近い場合にはデバッガ自身が実行できることを保証するために値を増やす。