(例へば、 10 * 10 の正方形と半径 10 の円の面積の和といった) 図形の面積を求める ことを考えてみましょう。
正方形の面積は 1 辺の長さの 2 乗です。このための式は (* 10 10) になります。ま た、円の面積は pi(約 3) かける半径の 2 乗です。このための式は (* 3 (* 10 10)) になります。 Emacs Lisp を用いると、求めたい面積は次のようになります。
(setq square (* 10 10)) => 100 (setq circle (* 3 quare)) => 300 (+ square circle) => 400
Emacs をプログラムするのが私だけならこれでよいのですが、(実際は) 他の人の書い たプログラムを用いているのであり、変数 square を用いているひともいるかもしれま せん。他の変数を混乱させずに、この計算を行ないたいということがあります。
これを Lisp で行なうためには、 (変数に対し)ローカルバインディングと呼ばれるも のを作ります。 (ある変数に対し)ローカルバインディングを持つということは、その 変数に対し、コードのある部分でのみ有効な値を与えることができることを意味しま す。その式を出ると、その "ローカル" 値は消え、変数はそれ以前の値を回復(訳注: regain)します。
紙の上でこの計算を行なうことを想像してみて下さい。他の人がプログラムに用いる紙 が 1枚あります。私は、私自身の計算を行なうのに 1枚(別の)紙を用います。
他の人のプログラムが走る場合、それはその人の紙を用います。 (それは)その紙の上 に square = 55 と "書く" かもしれません。私が計算を行なう時、私は自分の紙を(そ の)上に置きそこに square = 100 と書きます。私は(計算を)終えると自分の紙を取り さるため、他のプログラムが再びその机を "見る" と、それは (私が何も変更しなかっ たかのように) square = 55 と書かれた最初の紙を見ることになります。
Lisp でローカルバインディングを作るには、let と呼ばれるものを用います。それに ローカルで用いたい変数のリストを続け、(その後) そのローカルバインディングで評 価したい式を(全て) 続けます。
let の評価が終ると、それはその中の最後の式 (以下の例では (+ square circle))の 値を返し、let で確立されたローカル変数は(全て)消滅します。
以下の例は let の中で面積の計算を行なうものです (この式の評価を行なうには、最 後の閉じの括弧の後で LFD をタイプします)。
(let (square circle) (setq square (* 10 10)) (setq circle (* 3 square)) (+ square circle)) => 400
square と circle がすでに値を持っている場合にも、この値は変更されずに保持され ます。
(setq square 1) => 1 (let (square circle) (setq square (* 10 10)) ;今 square は 100 (setq circle (* 3 square)) (+ square circle)) => 400 ;square は 再び 1 になっている square => 1
これを "let が、変数 square をローカルにバインドする" と言います。
1つの let が、一番上のレベルの変数に与えられた値を保持(訳注:protect)するよう に、let 中の let は最初の let の変数に与えられた値を保持します。
(setq number 6) => 6
(let (number) ;最初の let (setq number 7) ;number は 7 (let (number) ;2番目の let (setq number 73) ;number は 73 (setq x 8)) ;number はまた 7 number) ;number はまた 6 => 7 number => 6 x => 8