あいうえおlisp
小さい関数は書けるようになったつもりだったのですが、基礎の理解が乏しいのを実感したので前よりもうちょっとだけ深く、再入門することにしました。
set (#<system-function system::set-symbol-value>)
シンボルの値を設定する。
(set 'a 1); OK (set 'a 1 'b 2); エラー
複数のシンボルに値をbindできない。
setq (#<special-operator setq>)
変数に値をbindする。
(setq a 1); OK (setq a 1 b (1+ a)); OK
複数の変数を1度にbind可能。2番目の変数の値に1番目の変数の値をbind可能。
(set ‘a 1);aというシンボルに1をbindしてる。
と
(setq a 1);aという変数に1をbindしてる。
が同じ結果になる。
setf (#<macro #<compiled-function setf>>)
変数だけでなく、構造体の要素、配列の要素、リストの要素、その他の値をbindすることができる。
(setf a 1); OK (setf a 1 b (1+ a)); OK
複数の変数などに値をbindできる。2番目の変数の値に1番目の変数の値をbind可能。
(setq a 1); aという変数に1をbindしてる。
と
(setf a 1); aという変数に1をbindしてる。
が同じ結果になる。
(setq array (make-array 5)) (setf (aref array 2) 8) array; #(nil nil 8 nil nil)
setfは第一引数が式でもよいので配列などの要素へのbindも可能。
let (#<special-operator let>)
レキシカル環境を作成しながら、その環境内で有効な変数を定義する。
(let ((a 1) (b 2)) (+ a b)); OK
複数のレキシカルスコープの変数を定義可能
(let ((a 1) (b (1+ a))) (+ a b));
xyzzyでは、エラーになる。clispでは、エラーにならなかった。
let*
letとよく似ています。letと異なり、VARの初期化に先に定義した他のVARを参照
することが可能です。
http://xyzzy.s53.xrea.com/reference/wiki.cgi?p=let%2A
とすると、clispでは、let と let* の違いはないということか。
追記20070523 誤った情報の訂正です。
コメント欄で、NANRIさんから指摘いただいたとおり、clispでS式を連続して入力しながら確認してしまっていたため、直前に行なった(setf a 1)でbindした変数を参照していたためエラーになっていました。xyzzyとclispで同じ動作になりました。let*を使えば、2番目の変数にbindするときに、1番目の変数の値を利用できました。
今日のまとめ
これだけでも新しく知ることがいくつかありました。setq と setfの使い分けは意味もわからず適当だったけど、今後は自信を持って適当にできる?
NANRIさん、おせわになります。
>つまりグローバル環境の変数aを参照したからエラーにならなかったということです。
まさに、そのとおりでした(汗 clispを立ち上げ直後に実行するとエラーになりました。
さすがに自分のおっちょこちょい振りにあきれました。あとでエントリを修正追記しますm(_ _)m ありがとうございます。