変数の定義と代入
Lispにおける局所変数,大域変数,大域定数の定義と代入について.
letを使用すると,そのlet式内でのみ有効な新しい局所変数が使用できるようになる.
(let 変数設定のリスト 本体)変数設定のリストの各要素は以下の形式である.
(変数名 値)このリストで設定した値は本体で使用できるが,該当するlet式の外では使用できない.以下はlet式で変数a,bを導入して,本体の和を求めている.その後let式の外で変数aを参照すると,怒られる.
> (let ((a 1) (b 2)) (+ a b)) 3 > a *** - EVAL: variable A has no valuelet式自身の評価値は本体の最後の式の評価値である.
> (let ((a 1) (b 2)) (+ a b) (* a b)) 2
defparameterを使用すると,大域変数を設定できる.
(defparameter 変数名 値)以下は大域変数*hoge*を1に設定して,次の式でそれを参照している.
> (defparameter *hoge* 1) *HOGE* > *hoge* 1大域変数名は前後を*で囲うのがLispでの習慣らしい.ちなみに大域定数はdefconstantを使用する.
(defconstant 定数名 値)定数名とおなじ名前を変数名に使用しようとするとエラーとなる.
> (defconstant *a* 1) *A* > (defparameter *a* 10) *** - DEFPARAMETER: the constant *A* must not be redefined to be a variableシンボルが大域変数や大域定数の名前として使用されているかどうかはboudpでチェックできる.
(boundp シンボル)以下例.
> (boundp '*a*) NIL > (defparameter *a* 1) *A* > (boundp '*a*) T
変数に値を代入するには,setfを使用する.
(setf 変数名 値)次の例はletで局所変数aを設定し,let式本体で変数*hoge*,aに対してsetfしてaと*hoge*の和を求めている.
> (let ((a 1)) (setf *hoge* 1) (setf a (* a 10)) (+ a *hoge*)) 11 > *hoge* 1 > a *** - EVAL: variable A has no valueこのように,局所変数に使用されていない変数*hoge*に対してsetfすると,その変数*hoge*は大域変数と見なされる(※).
※いきなりsetfで大域変数を生成できるが,defparameterを使用する方が見やすいコードになる.
setfの第一引数に式を指定すると,第二引数は第一引数で参照された場所に挿入される.次の例はリストaを生成し,setfの第一引数でリストaの第三要素を参照することで,第二引数のhogeが第三要素に設定されている.
> (setf a '(1 2 3 4 5 6 7 8 9)) (1 2 3 4 5 6 7 8 9) > (setf (third a) 'hoge) HOGE > a (1 2 HOGE 4 5 6 7 8 9)